summaryrefslogtreecommitdiff
path: root/deps/v8/src
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2014-05-12 05:07:46 +0200
committerFedor Indutny <fedor@indutny.com>2014-06-12 17:46:17 -0700
commit3a280b2034e3ea438cd3a2e7acd1a4cd40112ac5 (patch)
treeae194faf83fd22ad890b421c2ebd537db1a52534 /deps/v8/src
parent5413d9abe0df7e22bdb650a65f4c0ac462bbe147 (diff)
downloadnode-new-3a280b2034e3ea438cd3a2e7acd1a4cd40112ac5.tar.gz
deps: upgrade v8 to 3.26.33
Signed-off-by: Fedor Indutny <fedor@indutny.com>
Diffstat (limited to 'deps/v8/src')
-rw-r--r--deps/v8/src/accessors.cc1227
-rw-r--r--deps/v8/src/accessors.h147
-rw-r--r--deps/v8/src/allocation-site-scopes.cc29
-rw-r--r--deps/v8/src/allocation-site-scopes.h27
-rw-r--r--deps/v8/src/allocation-tracker.cc38
-rw-r--r--deps/v8/src/allocation-tracker.h27
-rw-r--r--deps/v8/src/allocation.cc27
-rw-r--r--deps/v8/src/allocation.h27
-rw-r--r--deps/v8/src/api.cc1066
-rw-r--r--deps/v8/src/api.h35
-rw-r--r--deps/v8/src/apinatives.js61
-rw-r--r--deps/v8/src/arguments.cc27
-rw-r--r--deps/v8/src/arguments.h38
-rw-r--r--deps/v8/src/arm/assembler-arm-inl.h14
-rw-r--r--deps/v8/src/arm/assembler-arm.cc80
-rw-r--r--deps/v8/src/arm/assembler-arm.h27
-rw-r--r--deps/v8/src/arm/builtins-arm.cc65
-rw-r--r--deps/v8/src/arm/code-stubs-arm.cc929
-rw-r--r--deps/v8/src/arm/code-stubs-arm.h52
-rw-r--r--deps/v8/src/arm/codegen-arm.cc101
-rw-r--r--deps/v8/src/arm/codegen-arm.h27
-rw-r--r--deps/v8/src/arm/constants-arm.cc27
-rw-r--r--deps/v8/src/arm/constants-arm.h27
-rw-r--r--deps/v8/src/arm/cpu-arm.cc37
-rw-r--r--deps/v8/src/arm/debug-arm.cc68
-rw-r--r--deps/v8/src/arm/deoptimizer-arm.cc32
-rw-r--r--deps/v8/src/arm/disasm-arm.cc29
-rw-r--r--deps/v8/src/arm/frames-arm.cc27
-rw-r--r--deps/v8/src/arm/frames-arm.h27
-rw-r--r--deps/v8/src/arm/full-codegen-arm.cc279
-rw-r--r--deps/v8/src/arm/ic-arm.cc27
-rw-r--r--deps/v8/src/arm/lithium-arm.cc249
-rw-r--r--deps/v8/src/arm/lithium-arm.h69
-rw-r--r--deps/v8/src/arm/lithium-codegen-arm.cc412
-rw-r--r--deps/v8/src/arm/lithium-codegen-arm.h38
-rw-r--r--deps/v8/src/arm/lithium-gap-resolver-arm.cc98
-rw-r--r--deps/v8/src/arm/lithium-gap-resolver-arm.h31
-rw-r--r--deps/v8/src/arm/macro-assembler-arm.cc153
-rw-r--r--deps/v8/src/arm/macro-assembler-arm.h46
-rw-r--r--deps/v8/src/arm/regexp-macro-assembler-arm.cc31
-rw-r--r--deps/v8/src/arm/regexp-macro-assembler-arm.h27
-rw-r--r--deps/v8/src/arm/simulator-arm.cc33
-rw-r--r--deps/v8/src/arm/simulator-arm.h27
-rw-r--r--deps/v8/src/arm/stub-cache-arm.cc92
-rw-r--r--deps/v8/src/arm64/assembler-arm64-inl.h49
-rw-r--r--deps/v8/src/arm64/assembler-arm64.cc178
-rw-r--r--deps/v8/src/arm64/assembler-arm64.h91
-rw-r--r--deps/v8/src/arm64/builtins-arm64.cc67
-rw-r--r--deps/v8/src/arm64/code-stubs-arm64.cc1045
-rw-r--r--deps/v8/src/arm64/code-stubs-arm64.h78
-rw-r--r--deps/v8/src/arm64/codegen-arm64.cc69
-rw-r--r--deps/v8/src/arm64/codegen-arm64.h27
-rw-r--r--deps/v8/src/arm64/constants-arm64.h34
-rw-r--r--deps/v8/src/arm64/cpu-arm64.cc113
-rw-r--r--deps/v8/src/arm64/cpu-arm64.h52
-rw-r--r--deps/v8/src/arm64/debug-arm64.cc67
-rw-r--r--deps/v8/src/arm64/decoder-arm64-inl.h27
-rw-r--r--deps/v8/src/arm64/decoder-arm64.cc27
-rw-r--r--deps/v8/src/arm64/decoder-arm64.h27
-rw-r--r--deps/v8/src/arm64/deoptimizer-arm64.cc86
-rw-r--r--deps/v8/src/arm64/disasm-arm64.cc30
-rw-r--r--deps/v8/src/arm64/disasm-arm64.h27
-rw-r--r--deps/v8/src/arm64/frames-arm64.cc27
-rw-r--r--deps/v8/src/arm64/frames-arm64.h27
-rw-r--r--deps/v8/src/arm64/full-codegen-arm64.cc307
-rw-r--r--deps/v8/src/arm64/ic-arm64.cc28
-rw-r--r--deps/v8/src/arm64/instructions-arm64.cc42
-rw-r--r--deps/v8/src/arm64/instructions-arm64.h46
-rw-r--r--deps/v8/src/arm64/instrument-arm64.cc27
-rw-r--r--deps/v8/src/arm64/instrument-arm64.h27
-rw-r--r--deps/v8/src/arm64/lithium-arm64.cc436
-rw-r--r--deps/v8/src/arm64/lithium-arm64.h175
-rw-r--r--deps/v8/src/arm64/lithium-codegen-arm64.cc771
-rw-r--r--deps/v8/src/arm64/lithium-codegen-arm64.h100
-rw-r--r--deps/v8/src/arm64/lithium-gap-resolver-arm64.cc27
-rw-r--r--deps/v8/src/arm64/lithium-gap-resolver-arm64.h27
-rw-r--r--deps/v8/src/arm64/macro-assembler-arm64-inl.h79
-rw-r--r--deps/v8/src/arm64/macro-assembler-arm64.cc336
-rw-r--r--deps/v8/src/arm64/macro-assembler-arm64.h141
-rw-r--r--deps/v8/src/arm64/regexp-macro-assembler-arm64.cc33
-rw-r--r--deps/v8/src/arm64/regexp-macro-assembler-arm64.h27
-rw-r--r--deps/v8/src/arm64/simulator-arm64.cc97
-rw-r--r--deps/v8/src/arm64/simulator-arm64.h28
-rw-r--r--deps/v8/src/arm64/stub-cache-arm64.cc96
-rw-r--r--deps/v8/src/arm64/utils-arm64.cc27
-rw-r--r--deps/v8/src/arm64/utils-arm64.h27
-rw-r--r--deps/v8/src/array-iterator.js15
-rw-r--r--deps/v8/src/array.js396
-rw-r--r--deps/v8/src/arraybuffer.js35
-rw-r--r--deps/v8/src/assembler.cc71
-rw-r--r--deps/v8/src/assembler.h37
-rw-r--r--deps/v8/src/assert-scope.h38
-rw-r--r--deps/v8/src/ast.cc62
-rw-r--r--deps/v8/src/ast.h131
-rw-r--r--deps/v8/src/atomicops.h30
-rw-r--r--deps/v8/src/atomicops_internals_arm64_gcc.h188
-rw-r--r--deps/v8/src/atomicops_internals_arm_gcc.h35
-rw-r--r--deps/v8/src/atomicops_internals_atomicword_compat.h27
-rw-r--r--deps/v8/src/atomicops_internals_mac.h35
-rw-r--r--deps/v8/src/atomicops_internals_mips_gcc.h35
-rw-r--r--deps/v8/src/atomicops_internals_tsan.h35
-rw-r--r--deps/v8/src/atomicops_internals_x86_gcc.cc35
-rw-r--r--deps/v8/src/atomicops_internals_x86_gcc.h35
-rw-r--r--deps/v8/src/atomicops_internals_x86_msvc.h35
-rw-r--r--deps/v8/src/base/macros.h76
-rw-r--r--deps/v8/src/bignum-dtoa.cc27
-rw-r--r--deps/v8/src/bignum-dtoa.h27
-rw-r--r--deps/v8/src/bignum.cc27
-rw-r--r--deps/v8/src/bignum.h27
-rw-r--r--deps/v8/src/bootstrapper.cc863
-rw-r--r--deps/v8/src/bootstrapper.h53
-rw-r--r--deps/v8/src/builtins.cc542
-rw-r--r--deps/v8/src/builtins.h37
-rw-r--r--deps/v8/src/bytecodes-irregexp.h27
-rw-r--r--deps/v8/src/cached-powers.cc27
-rw-r--r--deps/v8/src/cached-powers.h27
-rw-r--r--deps/v8/src/char-predicates-inl.h27
-rw-r--r--deps/v8/src/char-predicates.h27
-rw-r--r--deps/v8/src/checks.cc29
-rw-r--r--deps/v8/src/checks.h27
-rw-r--r--deps/v8/src/circular-queue-inl.h27
-rw-r--r--deps/v8/src/circular-queue.h27
-rw-r--r--deps/v8/src/code-stubs-hydrogen.cc160
-rw-r--r--deps/v8/src/code-stubs.cc158
-rw-r--r--deps/v8/src/code-stubs.h588
-rw-r--r--deps/v8/src/code.h27
-rw-r--r--deps/v8/src/codegen.cc101
-rw-r--r--deps/v8/src/codegen.h68
-rw-r--r--deps/v8/src/collection.js87
-rw-r--r--deps/v8/src/compilation-cache.cc193
-rw-r--r--deps/v8/src/compilation-cache.h90
-rw-r--r--deps/v8/src/compiler-intrinsics.h27
-rw-r--r--deps/v8/src/compiler.cc194
-rw-r--r--deps/v8/src/compiler.h70
-rw-r--r--deps/v8/src/contexts.cc40
-rw-r--r--deps/v8/src/contexts.h67
-rw-r--r--deps/v8/src/conversions-inl.h31
-rw-r--r--deps/v8/src/conversions.cc111
-rw-r--r--deps/v8/src/conversions.h115
-rw-r--r--deps/v8/src/counters.cc97
-rw-r--r--deps/v8/src/counters.h424
-rw-r--r--deps/v8/src/cpu-profiler-inl.h27
-rw-r--r--deps/v8/src/cpu-profiler.cc75
-rw-r--r--deps/v8/src/cpu-profiler.h27
-rw-r--r--deps/v8/src/cpu.cc27
-rw-r--r--deps/v8/src/cpu.h32
-rw-r--r--deps/v8/src/d8-debug.cc31
-rw-r--r--deps/v8/src/d8-debug.h27
-rw-r--r--deps/v8/src/d8-posix.cc27
-rw-r--r--deps/v8/src/d8-readline.cc27
-rw-r--r--deps/v8/src/d8-windows.cc27
-rw-r--r--deps/v8/src/d8.cc108
-rw-r--r--deps/v8/src/d8.h47
-rw-r--r--deps/v8/src/d8.js27
-rw-r--r--deps/v8/src/data-flow.cc27
-rw-r--r--deps/v8/src/data-flow.h27
-rw-r--r--deps/v8/src/date.cc32
-rw-r--r--deps/v8/src/date.h27
-rw-r--r--deps/v8/src/date.js27
-rw-r--r--deps/v8/src/dateparser-inl.h27
-rw-r--r--deps/v8/src/dateparser.cc27
-rw-r--r--deps/v8/src/dateparser.h27
-rw-r--r--deps/v8/src/debug-agent.cc37
-rw-r--r--deps/v8/src/debug-agent.h30
-rw-r--r--deps/v8/src/debug-debugger.js64
-rw-r--r--deps/v8/src/debug.cc650
-rw-r--r--deps/v8/src/debug.h131
-rw-r--r--deps/v8/src/deoptimizer.cc268
-rw-r--r--deps/v8/src/deoptimizer.h45
-rw-r--r--deps/v8/src/disasm.h27
-rw-r--r--deps/v8/src/disassembler.cc27
-rw-r--r--deps/v8/src/disassembler.h27
-rw-r--r--deps/v8/src/diy-fp.cc27
-rw-r--r--deps/v8/src/diy-fp.h27
-rw-r--r--deps/v8/src/double.h27
-rw-r--r--deps/v8/src/dtoa.cc27
-rw-r--r--deps/v8/src/dtoa.h27
-rw-r--r--deps/v8/src/effects.h27
-rw-r--r--deps/v8/src/elements-kind.cc92
-rw-r--r--deps/v8/src/elements-kind.h27
-rw-r--r--deps/v8/src/elements.cc675
-rw-r--r--deps/v8/src/elements.h162
-rw-r--r--deps/v8/src/execution.cc385
-rw-r--r--deps/v8/src/execution.h144
-rw-r--r--deps/v8/src/extensions/externalize-string-extension.cc27
-rw-r--r--deps/v8/src/extensions/externalize-string-extension.h27
-rw-r--r--deps/v8/src/extensions/free-buffer-extension.cc27
-rw-r--r--deps/v8/src/extensions/free-buffer-extension.h27
-rw-r--r--deps/v8/src/extensions/gc-extension.cc27
-rw-r--r--deps/v8/src/extensions/gc-extension.h27
-rw-r--r--deps/v8/src/extensions/statistics-extension.cc27
-rw-r--r--deps/v8/src/extensions/statistics-extension.h27
-rw-r--r--deps/v8/src/extensions/trigger-failure-extension.cc27
-rw-r--r--deps/v8/src/extensions/trigger-failure-extension.h27
-rw-r--r--deps/v8/src/factory.cc1740
-rw-r--r--deps/v8/src/factory.h385
-rw-r--r--deps/v8/src/fast-dtoa.cc27
-rw-r--r--deps/v8/src/fast-dtoa.h27
-rw-r--r--deps/v8/src/feedback-slots.h89
-rw-r--r--deps/v8/src/fixed-dtoa.cc27
-rw-r--r--deps/v8/src/fixed-dtoa.h27
-rw-r--r--deps/v8/src/flag-definitions.h60
-rw-r--r--deps/v8/src/flags.cc36
-rw-r--r--deps/v8/src/flags.h36
-rw-r--r--deps/v8/src/frames-inl.h27
-rw-r--r--deps/v8/src/frames.cc66
-rw-r--r--deps/v8/src/frames.h27
-rw-r--r--deps/v8/src/full-codegen.cc68
-rw-r--r--deps/v8/src/full-codegen.h56
-rw-r--r--deps/v8/src/func-name-inferrer.cc40
-rw-r--r--deps/v8/src/func-name-inferrer.h27
-rw-r--r--deps/v8/src/gdb-jit.cc36
-rw-r--r--deps/v8/src/gdb-jit.h27
-rw-r--r--deps/v8/src/generator.js27
-rw-r--r--deps/v8/src/global-handles.cc27
-rw-r--r--deps/v8/src/global-handles.h29
-rw-r--r--deps/v8/src/globals.h106
-rw-r--r--deps/v8/src/handles-inl.h45
-rw-r--r--deps/v8/src/handles.cc652
-rw-r--r--deps/v8/src/handles.h189
-rw-r--r--deps/v8/src/harmony-array.js73
-rw-r--r--deps/v8/src/harmony-math.js29
-rw-r--r--deps/v8/src/harmony-string.js39
-rw-r--r--deps/v8/src/hashmap.h32
-rw-r--r--deps/v8/src/heap-inl.h255
-rw-r--r--deps/v8/src/heap-profiler.cc27
-rw-r--r--deps/v8/src/heap-profiler.h27
-rw-r--r--deps/v8/src/heap-snapshot-generator-inl.h27
-rw-r--r--deps/v8/src/heap-snapshot-generator.cc195
-rw-r--r--deps/v8/src/heap-snapshot-generator.h48
-rw-r--r--deps/v8/src/heap.cc2595
-rw-r--r--deps/v8/src/heap.h939
-rw-r--r--deps/v8/src/hydrogen-alias-analysis.h27
-rw-r--r--deps/v8/src/hydrogen-bce.cc27
-rw-r--r--deps/v8/src/hydrogen-bce.h27
-rw-r--r--deps/v8/src/hydrogen-bch.cc27
-rw-r--r--deps/v8/src/hydrogen-bch.h27
-rw-r--r--deps/v8/src/hydrogen-canonicalize.cc27
-rw-r--r--deps/v8/src/hydrogen-canonicalize.h27
-rw-r--r--deps/v8/src/hydrogen-check-elimination.cc200
-rw-r--r--deps/v8/src/hydrogen-check-elimination.h27
-rw-r--r--deps/v8/src/hydrogen-dce.cc27
-rw-r--r--deps/v8/src/hydrogen-dce.h27
-rw-r--r--deps/v8/src/hydrogen-dehoist.cc27
-rw-r--r--deps/v8/src/hydrogen-dehoist.h27
-rw-r--r--deps/v8/src/hydrogen-environment-liveness.cc43
-rw-r--r--deps/v8/src/hydrogen-environment-liveness.h30
-rw-r--r--deps/v8/src/hydrogen-escape-analysis.cc51
-rw-r--r--deps/v8/src/hydrogen-escape-analysis.h29
-rw-r--r--deps/v8/src/hydrogen-flow-engine.h27
-rw-r--r--deps/v8/src/hydrogen-gvn.cc27
-rw-r--r--deps/v8/src/hydrogen-gvn.h27
-rw-r--r--deps/v8/src/hydrogen-infer-representation.cc27
-rw-r--r--deps/v8/src/hydrogen-infer-representation.h27
-rw-r--r--deps/v8/src/hydrogen-infer-types.cc27
-rw-r--r--deps/v8/src/hydrogen-infer-types.h27
-rw-r--r--deps/v8/src/hydrogen-instructions.cc381
-rw-r--r--deps/v8/src/hydrogen-instructions.h330
-rw-r--r--deps/v8/src/hydrogen-load-elimination.cc31
-rw-r--r--deps/v8/src/hydrogen-load-elimination.h27
-rw-r--r--deps/v8/src/hydrogen-mark-deoptimize.cc27
-rw-r--r--deps/v8/src/hydrogen-mark-deoptimize.h27
-rw-r--r--deps/v8/src/hydrogen-mark-unreachable.cc27
-rw-r--r--deps/v8/src/hydrogen-mark-unreachable.h27
-rw-r--r--deps/v8/src/hydrogen-osr.cc27
-rw-r--r--deps/v8/src/hydrogen-osr.h27
-rw-r--r--deps/v8/src/hydrogen-range-analysis.cc43
-rw-r--r--deps/v8/src/hydrogen-range-analysis.h28
-rw-r--r--deps/v8/src/hydrogen-redundant-phi.cc27
-rw-r--r--deps/v8/src/hydrogen-redundant-phi.h27
-rw-r--r--deps/v8/src/hydrogen-removable-simulates.cc67
-rw-r--r--deps/v8/src/hydrogen-removable-simulates.h27
-rw-r--r--deps/v8/src/hydrogen-representation-changes.cc27
-rw-r--r--deps/v8/src/hydrogen-representation-changes.h27
-rw-r--r--deps/v8/src/hydrogen-sce.cc27
-rw-r--r--deps/v8/src/hydrogen-sce.h27
-rw-r--r--deps/v8/src/hydrogen-store-elimination.cc29
-rw-r--r--deps/v8/src/hydrogen-store-elimination.h27
-rw-r--r--deps/v8/src/hydrogen-uint32-analysis.cc27
-rw-r--r--deps/v8/src/hydrogen-uint32-analysis.h27
-rw-r--r--deps/v8/src/hydrogen.cc524
-rw-r--r--deps/v8/src/hydrogen.h51
-rw-r--r--deps/v8/src/i18n.cc328
-rw-r--r--deps/v8/src/i18n.h27
-rw-r--r--deps/v8/src/i18n.js204
-rw-r--r--deps/v8/src/ia32/assembler-ia32-inl.h4
-rw-r--r--deps/v8/src/ia32/assembler-ia32.cc20
-rw-r--r--deps/v8/src/ia32/assembler-ia32.h16
-rw-r--r--deps/v8/src/ia32/builtins-ia32.cc75
-rw-r--r--deps/v8/src/ia32/code-stubs-ia32.cc876
-rw-r--r--deps/v8/src/ia32/code-stubs-ia32.h53
-rw-r--r--deps/v8/src/ia32/codegen-ia32.cc74
-rw-r--r--deps/v8/src/ia32/codegen-ia32.h27
-rw-r--r--deps/v8/src/ia32/cpu-ia32.cc37
-rw-r--r--deps/v8/src/ia32/debug-ia32.cc69
-rw-r--r--deps/v8/src/ia32/deoptimizer-ia32.cc27
-rw-r--r--deps/v8/src/ia32/disasm-ia32.cc27
-rw-r--r--deps/v8/src/ia32/frames-ia32.cc27
-rw-r--r--deps/v8/src/ia32/frames-ia32.h27
-rw-r--r--deps/v8/src/ia32/full-codegen-ia32.cc278
-rw-r--r--deps/v8/src/ia32/ic-ia32.cc29
-rw-r--r--deps/v8/src/ia32/lithium-codegen-ia32.cc405
-rw-r--r--deps/v8/src/ia32/lithium-codegen-ia32.h36
-rw-r--r--deps/v8/src/ia32/lithium-gap-resolver-ia32.cc27
-rw-r--r--deps/v8/src/ia32/lithium-gap-resolver-ia32.h27
-rw-r--r--deps/v8/src/ia32/lithium-ia32.cc169
-rw-r--r--deps/v8/src/ia32/lithium-ia32.h85
-rw-r--r--deps/v8/src/ia32/macro-assembler-ia32.cc88
-rw-r--r--deps/v8/src/ia32/macro-assembler-ia32.h42
-rw-r--r--deps/v8/src/ia32/regexp-macro-assembler-ia32.cc29
-rw-r--r--deps/v8/src/ia32/regexp-macro-assembler-ia32.h27
-rw-r--r--deps/v8/src/ia32/simulator-ia32.cc27
-rw-r--r--deps/v8/src/ia32/simulator-ia32.h27
-rw-r--r--deps/v8/src/ia32/stub-cache-ia32.cc91
-rw-r--r--deps/v8/src/ic-inl.h33
-rw-r--r--deps/v8/src/ic.cc916
-rw-r--r--deps/v8/src/ic.h226
-rw-r--r--deps/v8/src/icu_util.cc27
-rw-r--r--deps/v8/src/icu_util.h27
-rw-r--r--deps/v8/src/incremental-marking-inl.h31
-rw-r--r--deps/v8/src/incremental-marking.cc47
-rw-r--r--deps/v8/src/incremental-marking.h27
-rw-r--r--deps/v8/src/interface.cc27
-rw-r--r--deps/v8/src/interface.h27
-rw-r--r--deps/v8/src/interpreter-irregexp.cc27
-rw-r--r--deps/v8/src/interpreter-irregexp.h27
-rw-r--r--deps/v8/src/isolate-inl.h36
-rw-r--r--deps/v8/src/isolate.cc451
-rw-r--r--deps/v8/src/isolate.h226
-rw-r--r--deps/v8/src/json-parser.h75
-rw-r--r--deps/v8/src/json-stringifier.h250
-rw-r--r--deps/v8/src/json.js27
-rw-r--r--deps/v8/src/jsregexp-inl.h27
-rw-r--r--deps/v8/src/jsregexp.cc129
-rw-r--r--deps/v8/src/jsregexp.h60
-rw-r--r--deps/v8/src/lazy-instance.h37
-rw-r--r--deps/v8/src/libplatform/default-platform.cc34
-rw-r--r--deps/v8/src/libplatform/default-platform.h32
-rw-r--r--deps/v8/src/libplatform/task-queue.cc27
-rw-r--r--deps/v8/src/libplatform/task-queue.h30
-rw-r--r--deps/v8/src/libplatform/worker-thread.cc27
-rw-r--r--deps/v8/src/libplatform/worker-thread.h30
-rw-r--r--deps/v8/src/list-inl.h27
-rw-r--r--deps/v8/src/list.h27
-rw-r--r--deps/v8/src/lithium-allocator-inl.h27
-rw-r--r--deps/v8/src/lithium-allocator.cc42
-rw-r--r--deps/v8/src/lithium-allocator.h27
-rw-r--r--deps/v8/src/lithium-codegen.cc89
-rw-r--r--deps/v8/src/lithium-codegen.h38
-rw-r--r--deps/v8/src/lithium.cc57
-rw-r--r--deps/v8/src/lithium.h64
-rw-r--r--deps/v8/src/liveedit-debugger.js27
-rw-r--r--deps/v8/src/liveedit.cc409
-rw-r--r--deps/v8/src/liveedit.h206
-rw-r--r--deps/v8/src/log-inl.h27
-rw-r--r--deps/v8/src/log-utils.cc28
-rw-r--r--deps/v8/src/log-utils.h35
-rw-r--r--deps/v8/src/log.cc88
-rw-r--r--deps/v8/src/log.h31
-rw-r--r--deps/v8/src/macro-assembler.h27
-rw-r--r--deps/v8/src/macros.py11
-rw-r--r--deps/v8/src/mark-compact-inl.h27
-rw-r--r--deps/v8/src/mark-compact.cc292
-rw-r--r--deps/v8/src/mark-compact.h79
-rw-r--r--deps/v8/src/math.js39
-rw-r--r--deps/v8/src/messages.cc53
-rw-r--r--deps/v8/src/messages.h27
-rw-r--r--deps/v8/src/messages.js89
-rw-r--r--deps/v8/src/mips/assembler-mips-inl.h6
-rw-r--r--deps/v8/src/mips/assembler-mips.cc35
-rw-r--r--deps/v8/src/mips/assembler-mips.h29
-rw-r--r--deps/v8/src/mips/builtins-mips.cc81
-rw-r--r--deps/v8/src/mips/code-stubs-mips.cc928
-rw-r--r--deps/v8/src/mips/code-stubs-mips.h60
-rw-r--r--deps/v8/src/mips/codegen-mips.cc427
-rw-r--r--deps/v8/src/mips/codegen-mips.h27
-rw-r--r--deps/v8/src/mips/constants-mips.cc27
-rw-r--r--deps/v8/src/mips/constants-mips.h48
-rw-r--r--deps/v8/src/mips/cpu-mips.cc37
-rw-r--r--deps/v8/src/mips/debug-mips.cc71
-rw-r--r--deps/v8/src/mips/deoptimizer-mips.cc29
-rw-r--r--deps/v8/src/mips/disasm-mips.cc27
-rw-r--r--deps/v8/src/mips/frames-mips.cc27
-rw-r--r--deps/v8/src/mips/frames-mips.h27
-rw-r--r--deps/v8/src/mips/full-codegen-mips.cc266
-rw-r--r--deps/v8/src/mips/ic-mips.cc29
-rw-r--r--deps/v8/src/mips/lithium-codegen-mips.cc367
-rw-r--r--deps/v8/src/mips/lithium-codegen-mips.h51
-rw-r--r--deps/v8/src/mips/lithium-gap-resolver-mips.cc27
-rw-r--r--deps/v8/src/mips/lithium-gap-resolver-mips.h27
-rw-r--r--deps/v8/src/mips/lithium-mips.cc249
-rw-r--r--deps/v8/src/mips/lithium-mips.h67
-rw-r--r--deps/v8/src/mips/macro-assembler-mips.cc161
-rw-r--r--deps/v8/src/mips/macro-assembler-mips.h44
-rw-r--r--deps/v8/src/mips/regexp-macro-assembler-mips.cc31
-rw-r--r--deps/v8/src/mips/regexp-macro-assembler-mips.h27
-rw-r--r--deps/v8/src/mips/simulator-mips.cc27
-rw-r--r--deps/v8/src/mips/simulator-mips.h27
-rw-r--r--deps/v8/src/mips/stub-cache-mips.cc94
-rw-r--r--deps/v8/src/mirror-debugger.js90
-rw-r--r--deps/v8/src/misc-intrinsics.h27
-rw-r--r--deps/v8/src/mksnapshot.cc348
-rw-r--r--deps/v8/src/msan.h37
-rw-r--r--deps/v8/src/natives.h27
-rw-r--r--deps/v8/src/object-observe.js82
-rw-r--r--deps/v8/src/objects-debug.cc164
-rw-r--r--deps/v8/src/objects-inl.h1355
-rw-r--r--deps/v8/src/objects-printer.cc110
-rw-r--r--deps/v8/src/objects-visiting-inl.h65
-rw-r--r--deps/v8/src/objects-visiting.cc306
-rw-r--r--deps/v8/src/objects-visiting.h41
-rw-r--r--deps/v8/src/objects.cc7911
-rw-r--r--deps/v8/src/objects.h2503
-rw-r--r--deps/v8/src/once.cc27
-rw-r--r--deps/v8/src/once.h27
-rw-r--r--deps/v8/src/optimizing-compiler-thread.cc27
-rw-r--r--deps/v8/src/optimizing-compiler-thread.h27
-rw-r--r--deps/v8/src/parser.cc664
-rw-r--r--deps/v8/src/parser.h176
-rw-r--r--deps/v8/src/platform-cygwin.cc29
-rw-r--r--deps/v8/src/platform-freebsd.cc28
-rw-r--r--deps/v8/src/platform-linux.cc28
-rw-r--r--deps/v8/src/platform-macos.cc29
-rw-r--r--deps/v8/src/platform-openbsd.cc28
-rw-r--r--deps/v8/src/platform-posix.cc68
-rw-r--r--deps/v8/src/platform-qnx.cc28
-rw-r--r--deps/v8/src/platform-solaris.cc28
-rw-r--r--deps/v8/src/platform-win32.cc95
-rw-r--r--deps/v8/src/platform.h38
-rw-r--r--deps/v8/src/platform/condition-variable.cc27
-rw-r--r--deps/v8/src/platform/condition-variable.h27
-rw-r--r--deps/v8/src/platform/elapsed-timer.h27
-rw-r--r--deps/v8/src/platform/mutex.cc27
-rw-r--r--deps/v8/src/platform/mutex.h27
-rw-r--r--deps/v8/src/platform/semaphore.cc27
-rw-r--r--deps/v8/src/platform/semaphore.h27
-rw-r--r--deps/v8/src/platform/socket.cc27
-rw-r--r--deps/v8/src/platform/socket.h27
-rw-r--r--deps/v8/src/platform/time.cc27
-rw-r--r--deps/v8/src/platform/time.h27
-rw-r--r--deps/v8/src/preparse-data-format.h37
-rw-r--r--deps/v8/src/preparse-data.cc154
-rw-r--r--deps/v8/src/preparse-data.h104
-rw-r--r--deps/v8/src/preparser.cc59
-rw-r--r--deps/v8/src/preparser.h262
-rw-r--r--deps/v8/src/prettyprinter.cc27
-rw-r--r--deps/v8/src/prettyprinter.h27
-rw-r--r--deps/v8/src/profile-generator-inl.h27
-rw-r--r--deps/v8/src/profile-generator.cc45
-rw-r--r--deps/v8/src/profile-generator.h43
-rw-r--r--deps/v8/src/promise.js69
-rw-r--r--deps/v8/src/property-details-inl.h29
-rw-r--r--deps/v8/src/property-details.h30
-rw-r--r--deps/v8/src/property.cc70
-rw-r--r--deps/v8/src/property.h272
-rw-r--r--deps/v8/src/proxy.js27
-rw-r--r--deps/v8/src/qnx-math.h27
-rw-r--r--deps/v8/src/regexp-macro-assembler-irregexp-inl.h27
-rw-r--r--deps/v8/src/regexp-macro-assembler-irregexp.cc27
-rw-r--r--deps/v8/src/regexp-macro-assembler-irregexp.h27
-rw-r--r--deps/v8/src/regexp-macro-assembler-tracer.cc27
-rw-r--r--deps/v8/src/regexp-macro-assembler-tracer.h27
-rw-r--r--deps/v8/src/regexp-macro-assembler.cc27
-rw-r--r--deps/v8/src/regexp-macro-assembler.h27
-rw-r--r--deps/v8/src/regexp-stack.cc27
-rw-r--r--deps/v8/src/regexp-stack.h27
-rw-r--r--deps/v8/src/regexp.js30
-rw-r--r--deps/v8/src/rewriter.cc27
-rw-r--r--deps/v8/src/rewriter.h27
-rw-r--r--deps/v8/src/runtime-profiler.cc37
-rw-r--r--deps/v8/src/runtime-profiler.h27
-rw-r--r--deps/v8/src/runtime.cc5366
-rw-r--r--deps/v8/src/runtime.h165
-rw-r--r--deps/v8/src/runtime.js29
-rw-r--r--deps/v8/src/safepoint-table.cc27
-rw-r--r--deps/v8/src/safepoint-table.h27
-rw-r--r--deps/v8/src/sampler.cc28
-rw-r--r--deps/v8/src/sampler.h28
-rw-r--r--deps/v8/src/scanner-character-streams.cc29
-rw-r--r--deps/v8/src/scanner-character-streams.h28
-rw-r--r--deps/v8/src/scanner.cc45
-rw-r--r--deps/v8/src/scanner.h29
-rw-r--r--deps/v8/src/scopeinfo.cc126
-rw-r--r--deps/v8/src/scopeinfo.h35
-rw-r--r--deps/v8/src/scopes.cc33
-rw-r--r--deps/v8/src/scopes.h27
-rw-r--r--deps/v8/src/serialize.cc149
-rw-r--r--deps/v8/src/serialize.h66
-rw-r--r--deps/v8/src/simulator.h27
-rw-r--r--deps/v8/src/small-pointer-list.h27
-rw-r--r--deps/v8/src/smart-pointers.h27
-rw-r--r--deps/v8/src/snapshot-common.cc27
-rw-r--r--deps/v8/src/snapshot-empty.cc27
-rw-r--r--deps/v8/src/snapshot.h27
-rw-r--r--deps/v8/src/spaces-inl.h33
-rw-r--r--deps/v8/src/spaces.cc228
-rw-r--r--deps/v8/src/spaces.h153
-rw-r--r--deps/v8/src/splay-tree-inl.h27
-rw-r--r--deps/v8/src/splay-tree.h27
-rw-r--r--deps/v8/src/store-buffer-inl.h27
-rw-r--r--deps/v8/src/store-buffer.cc68
-rw-r--r--deps/v8/src/store-buffer.h27
-rw-r--r--deps/v8/src/string-search.cc27
-rw-r--r--deps/v8/src/string-search.h27
-rw-r--r--deps/v8/src/string-stream.cc38
-rw-r--r--deps/v8/src/string-stream.h59
-rw-r--r--deps/v8/src/string.js37
-rw-r--r--deps/v8/src/strtod.cc27
-rw-r--r--deps/v8/src/strtod.h27
-rw-r--r--deps/v8/src/stub-cache.cc126
-rw-r--r--deps/v8/src/stub-cache.h45
-rw-r--r--deps/v8/src/sweeper-thread.cc36
-rw-r--r--deps/v8/src/sweeper-thread.h30
-rw-r--r--deps/v8/src/symbol.js27
-rw-r--r--deps/v8/src/third_party/vtune/vtune-jit.cc7
-rw-r--r--deps/v8/src/token.cc27
-rw-r--r--deps/v8/src/token.h27
-rw-r--r--deps/v8/src/transitions-inl.h33
-rw-r--r--deps/v8/src/transitions.cc156
-rw-r--r--deps/v8/src/transitions.h69
-rw-r--r--deps/v8/src/trig-table.h27
-rw-r--r--deps/v8/src/type-info.cc71
-rw-r--r--deps/v8/src/type-info.h28
-rw-r--r--deps/v8/src/typedarray.js135
-rw-r--r--deps/v8/src/types-inl.h352
-rw-r--r--deps/v8/src/types.cc518
-rw-r--r--deps/v8/src/types.h665
-rw-r--r--deps/v8/src/typing.cc36
-rw-r--r--deps/v8/src/typing.h27
-rw-r--r--deps/v8/src/unbound-queue-inl.h27
-rw-r--r--deps/v8/src/unbound-queue.h27
-rw-r--r--deps/v8/src/unicode-inl.h27
-rw-r--r--deps/v8/src/unicode.cc27
-rw-r--r--deps/v8/src/unicode.h27
-rw-r--r--deps/v8/src/unique.h69
-rw-r--r--deps/v8/src/uri.h64
-rw-r--r--deps/v8/src/uri.js27
-rw-r--r--deps/v8/src/utils-inl.h27
-rw-r--r--deps/v8/src/utils.cc269
-rw-r--r--deps/v8/src/utils.h634
-rw-r--r--deps/v8/src/utils/random-number-generator.cc27
-rw-r--r--deps/v8/src/utils/random-number-generator.h27
-rw-r--r--deps/v8/src/v8-counters.cc104
-rw-r--r--deps/v8/src/v8-counters.h435
-rw-r--r--deps/v8/src/v8.cc120
-rw-r--r--deps/v8/src/v8.h40
-rw-r--r--deps/v8/src/v8checks.h27
-rw-r--r--deps/v8/src/v8conversions.cc132
-rw-r--r--deps/v8/src/v8conversions.h113
-rw-r--r--deps/v8/src/v8dll-main.cc27
-rw-r--r--deps/v8/src/v8globals.h46
-rw-r--r--deps/v8/src/v8memory.h27
-rw-r--r--deps/v8/src/v8natives.js45
-rw-r--r--deps/v8/src/v8threads.cc48
-rw-r--r--deps/v8/src/v8threads.h27
-rw-r--r--deps/v8/src/v8utils.cc276
-rw-r--r--deps/v8/src/v8utils.h464
-rw-r--r--deps/v8/src/variables.cc31
-rw-r--r--deps/v8/src/variables.h35
-rw-r--r--deps/v8/src/vector.h171
-rw-r--r--deps/v8/src/version.cc4
-rw-r--r--deps/v8/src/version.h27
-rw-r--r--deps/v8/src/vm-state-inl.h27
-rw-r--r--deps/v8/src/vm-state.h27
-rw-r--r--deps/v8/src/weak_collection.js27
-rw-r--r--deps/v8/src/win32-headers.h27
-rw-r--r--deps/v8/src/win32-math.cc27
-rw-r--r--deps/v8/src/win32-math.h27
-rw-r--r--deps/v8/src/x64/assembler-x64-inl.h38
-rw-r--r--deps/v8/src/x64/assembler-x64.cc209
-rw-r--r--deps/v8/src/x64/assembler-x64.h403
-rw-r--r--deps/v8/src/x64/builtins-x64.cc88
-rw-r--r--deps/v8/src/x64/code-stubs-x64.cc908
-rw-r--r--deps/v8/src/x64/code-stubs-x64.h50
-rw-r--r--deps/v8/src/x64/codegen-x64.cc99
-rw-r--r--deps/v8/src/x64/codegen-x64.h27
-rw-r--r--deps/v8/src/x64/cpu-x64.cc37
-rw-r--r--deps/v8/src/x64/debug-x64.cc72
-rw-r--r--deps/v8/src/x64/deoptimizer-x64.cc43
-rw-r--r--deps/v8/src/x64/disasm-x64.cc27
-rw-r--r--deps/v8/src/x64/frames-x64.cc27
-rw-r--r--deps/v8/src/x64/frames-x64.h38
-rw-r--r--deps/v8/src/x64/full-codegen-x64.cc319
-rw-r--r--deps/v8/src/x64/ic-x64.cc35
-rw-r--r--deps/v8/src/x64/lithium-codegen-x64.cc553
-rw-r--r--deps/v8/src/x64/lithium-codegen-x64.h35
-rw-r--r--deps/v8/src/x64/lithium-gap-resolver-x64.cc27
-rw-r--r--deps/v8/src/x64/lithium-gap-resolver-x64.h27
-rw-r--r--deps/v8/src/x64/lithium-x64.cc188
-rw-r--r--deps/v8/src/x64/lithium-x64.h72
-rw-r--r--deps/v8/src/x64/macro-assembler-x64.cc500
-rw-r--r--deps/v8/src/x64/macro-assembler-x64.h82
-rw-r--r--deps/v8/src/x64/regexp-macro-assembler-x64.cc77
-rw-r--r--deps/v8/src/x64/regexp-macro-assembler-x64.h74
-rw-r--r--deps/v8/src/x64/simulator-x64.cc27
-rw-r--r--deps/v8/src/x64/simulator-x64.h27
-rw-r--r--deps/v8/src/x64/stub-cache-x64.cc88
-rw-r--r--deps/v8/src/zone-allocator.h39
-rw-r--r--deps/v8/src/zone-containers.h27
-rw-r--r--deps/v8/src/zone-inl.h28
-rw-r--r--deps/v8/src/zone.cc27
-rw-r--r--deps/v8/src/zone.h27
602 files changed, 32901 insertions, 44492 deletions
diff --git a/deps/v8/src/accessors.cc b/deps/v8/src/accessors.cc
index 35cff1af7d..8c8fcdd999 100644
--- a/deps/v8/src/accessors.cc
+++ b/deps/v8/src/accessors.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
#include "accessors.h"
@@ -37,11 +14,33 @@
#include "isolate.h"
#include "list-inl.h"
#include "property-details.h"
+#include "api.h"
namespace v8 {
namespace internal {
+Handle<AccessorInfo> Accessors::MakeAccessor(
+ Isolate* isolate,
+ Handle<String> name,
+ AccessorGetterCallback getter,
+ AccessorSetterCallback setter,
+ PropertyAttributes attributes) {
+ Factory* factory = isolate->factory();
+ Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo();
+ info->set_property_attributes(attributes);
+ info->set_all_can_read(false);
+ info->set_all_can_write(false);
+ info->set_prohibits_overwriting(false);
+ info->set_name(*name);
+ Handle<Object> get = v8::FromCData(isolate, getter);
+ Handle<Object> set = v8::FromCData(isolate, setter);
+ info->set_getter(*get);
+ info->set_setter(*set);
+ return info;
+}
+
+
template <class C>
static C* FindInstanceOf(Isolate* isolate, Object* obj) {
for (Object* cur = obj; !cur->IsNull(); cur = cur->GetPrototype(isolate)) {
@@ -51,39 +50,11 @@ static C* FindInstanceOf(Isolate* isolate, Object* obj) {
}
-// Entry point that never should be called.
-MaybeObject* Accessors::IllegalSetter(Isolate* isolate,
- JSObject*,
- Object*,
- void*) {
- UNREACHABLE();
- return NULL;
-}
-
-
-Object* Accessors::IllegalGetAccessor(Isolate* isolate,
- Object* object,
- void*) {
- UNREACHABLE();
- return object;
-}
-
-
-MaybeObject* Accessors::ReadOnlySetAccessor(Isolate* isolate,
- JSObject*,
- Object* value,
- void*) {
- // According to ECMA-262, section 8.6.2.2, page 28, setting
- // read-only properties must be silently ignored.
- return value;
-}
-
-
static V8_INLINE bool CheckForName(Handle<String> name,
- String* property_name,
+ Handle<String> property_name,
int offset,
int* object_offset) {
- if (name->Equals(property_name)) {
+ if (String::Equals(name, property_name)) {
*object_offset = offset;
return true;
}
@@ -100,35 +71,35 @@ bool Accessors::IsJSObjectFieldAccessor(typename T::TypeHandle type,
Isolate* isolate = name->GetIsolate();
if (type->Is(T::String())) {
- return CheckForName(name, isolate->heap()->length_string(),
+ return CheckForName(name, isolate->factory()->length_string(),
String::kLengthOffset, object_offset);
}
if (!type->IsClass()) return false;
- Handle<Map> map = type->AsClass();
+ Handle<Map> map = type->AsClass()->Map();
switch (map->instance_type()) {
case JS_ARRAY_TYPE:
return
- CheckForName(name, isolate->heap()->length_string(),
+ CheckForName(name, isolate->factory()->length_string(),
JSArray::kLengthOffset, object_offset);
case JS_TYPED_ARRAY_TYPE:
return
- CheckForName(name, isolate->heap()->length_string(),
+ CheckForName(name, isolate->factory()->length_string(),
JSTypedArray::kLengthOffset, object_offset) ||
- CheckForName(name, isolate->heap()->byte_length_string(),
+ CheckForName(name, isolate->factory()->byte_length_string(),
JSTypedArray::kByteLengthOffset, object_offset) ||
- CheckForName(name, isolate->heap()->byte_offset_string(),
+ CheckForName(name, isolate->factory()->byte_offset_string(),
JSTypedArray::kByteOffsetOffset, object_offset);
case JS_ARRAY_BUFFER_TYPE:
return
- CheckForName(name, isolate->heap()->byte_length_string(),
+ CheckForName(name, isolate->factory()->byte_length_string(),
JSArrayBuffer::kByteLengthOffset, object_offset);
case JS_DATA_VIEW_TYPE:
return
- CheckForName(name, isolate->heap()->byte_length_string(),
+ CheckForName(name, isolate->factory()->byte_length_string(),
JSDataView::kByteLengthOffset, object_offset) ||
- CheckForName(name, isolate->heap()->byte_offset_string(),
+ CheckForName(name, isolate->factory()->byte_offset_string(),
JSDataView::kByteOffsetOffset, object_offset);
default:
return false;
@@ -153,15 +124,6 @@ bool Accessors::IsJSObjectFieldAccessor<HeapType>(Handle<HeapType> type,
//
-MaybeObject* Accessors::ArrayGetLength(Isolate* isolate,
- Object* object,
- void*) {
- // Traverse the prototype chain until we reach an array.
- JSArray* holder = FindInstanceOf<JSArray>(isolate, object);
- return holder == NULL ? Smi::FromInt(0) : holder->length();
-}
-
-
// The helper function will 'flatten' Number objects.
Handle<Object> Accessors::FlattenNumber(Isolate* isolate,
Handle<Object> value) {
@@ -178,174 +140,306 @@ Handle<Object> Accessors::FlattenNumber(Isolate* isolate,
}
-MaybeObject* Accessors::ArraySetLength(Isolate* isolate,
- JSObject* object_raw,
- Object* value_raw,
- void*) {
+void Accessors::ArrayLengthGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ DisallowHeapAllocation no_allocation;
HandleScope scope(isolate);
- Handle<JSObject> object(object_raw, isolate);
- Handle<Object> value(value_raw, isolate);
+ Object* object = *Utils::OpenHandle(*info.This());
+ // Traverse the prototype chain until we reach an array.
+ JSArray* holder = FindInstanceOf<JSArray>(isolate, object);
+ Object* result;
+ if (holder != NULL) {
+ result = holder->length();
+ } else {
+ result = Smi::FromInt(0);
+ }
+ info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
+}
+
+void Accessors::ArrayLengthSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> val,
+ const v8::PropertyCallbackInfo<void>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ HandleScope scope(isolate);
+ Handle<JSObject> object = Handle<JSObject>::cast(
+ Utils::OpenHandle(*info.This()));
+ Handle<Object> value = Utils::OpenHandle(*val);
// This means one of the object's prototypes is a JSArray and the
// object does not have a 'length' property. Calling SetProperty
// causes an infinite loop.
if (!object->IsJSArray()) {
- Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(object,
- isolate->factory()->length_string(), value, NONE);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
- return *result;
+ MaybeHandle<Object> maybe_result =
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ object, isolate->factory()->length_string(), value, NONE);
+ maybe_result.Check();
+ return;
}
value = FlattenNumber(isolate, value);
Handle<JSArray> array_handle = Handle<JSArray>::cast(object);
-
- bool has_exception;
- Handle<Object> uint32_v =
- Execution::ToUint32(isolate, value, &has_exception);
- if (has_exception) return Failure::Exception();
- Handle<Object> number_v =
- Execution::ToNumber(isolate, value, &has_exception);
- if (has_exception) return Failure::Exception();
+ MaybeHandle<Object> maybe;
+ Handle<Object> uint32_v;
+ maybe = Execution::ToUint32(isolate, value);
+ if (!maybe.ToHandle(&uint32_v)) {
+ isolate->OptionalRescheduleException(false);
+ return;
+ }
+ Handle<Object> number_v;
+ maybe = Execution::ToNumber(isolate, value);
+ if (!maybe.ToHandle(&number_v)) {
+ isolate->OptionalRescheduleException(false);
+ return;
+ }
if (uint32_v->Number() == number_v->Number()) {
- Handle<Object> result = JSArray::SetElementsLength(array_handle, uint32_v);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
- return *result;
+ maybe = JSArray::SetElementsLength(array_handle, uint32_v);
+ maybe.Check();
+ return;
}
- return isolate->Throw(
+
+ isolate->ScheduleThrow(
*isolate->factory()->NewRangeError("invalid_array_length",
HandleVector<Object>(NULL, 0)));
}
-const AccessorDescriptor Accessors::ArrayLength = {
- ArrayGetLength,
- ArraySetLength,
- 0
-};
+Handle<AccessorInfo> Accessors::ArrayLengthInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ return MakeAccessor(isolate,
+ isolate->factory()->length_string(),
+ &ArrayLengthGetter,
+ &ArrayLengthSetter,
+ attributes);
+}
+
//
// Accessors::StringLength
//
+void Accessors::StringLengthGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ DisallowHeapAllocation no_allocation;
+ HandleScope scope(isolate);
+ Object* value = *Utils::OpenHandle(*info.This());
+ Object* result;
+ if (value->IsJSValue()) value = JSValue::cast(value)->value();
+ if (value->IsString()) {
+ result = Smi::FromInt(String::cast(value)->length());
+ } else {
+ // If object is not a string we return 0 to be compatible with WebKit.
+ // Note: Firefox returns the length of ToString(object).
+ result = Smi::FromInt(0);
+ }
+ info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
+}
+
-MaybeObject* Accessors::StringGetLength(Isolate* isolate,
- Object* object,
- void*) {
- Object* value = object;
- if (object->IsJSValue()) value = JSValue::cast(object)->value();
- if (value->IsString()) return Smi::FromInt(String::cast(value)->length());
- // If object is not a string we return 0 to be compatible with WebKit.
- // Note: Firefox returns the length of ToString(object).
- return Smi::FromInt(0);
+void Accessors::StringLengthSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
}
-const AccessorDescriptor Accessors::StringLength = {
- StringGetLength,
- IllegalSetter,
- 0
-};
+Handle<AccessorInfo> Accessors::StringLengthInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ return MakeAccessor(isolate,
+ isolate->factory()->length_string(),
+ &StringLengthGetter,
+ &StringLengthSetter,
+ attributes);
+}
//
-// Accessors::ScriptSource
+// Accessors::ScriptColumnOffset
//
-MaybeObject* Accessors::ScriptGetSource(Isolate* isolate,
- Object* object,
- void*) {
- Object* script = JSValue::cast(object)->value();
- return Script::cast(script)->source();
+void Accessors::ScriptColumnOffsetGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ DisallowHeapAllocation no_allocation;
+ HandleScope scope(isolate);
+ Object* object = *Utils::OpenHandle(*info.This());
+ Object* res = Script::cast(JSValue::cast(object)->value())->column_offset();
+ info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
}
-const AccessorDescriptor Accessors::ScriptSource = {
- ScriptGetSource,
- IllegalSetter,
- 0
-};
+void Accessors::ScriptColumnOffsetSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptColumnOffsetInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ Handle<String> name(isolate->factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("column_offset")));
+ return MakeAccessor(isolate,
+ name,
+ &ScriptColumnOffsetGetter,
+ &ScriptColumnOffsetSetter,
+ attributes);
+}
//
-// Accessors::ScriptName
+// Accessors::ScriptId
//
-MaybeObject* Accessors::ScriptGetName(Isolate* isolate,
- Object* object,
- void*) {
- Object* script = JSValue::cast(object)->value();
- return Script::cast(script)->name();
+void Accessors::ScriptIdGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ DisallowHeapAllocation no_allocation;
+ HandleScope scope(isolate);
+ Object* object = *Utils::OpenHandle(*info.This());
+ Object* id = Script::cast(JSValue::cast(object)->value())->id();
+ info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(id, isolate)));
}
-const AccessorDescriptor Accessors::ScriptName = {
- ScriptGetName,
- IllegalSetter,
- 0
-};
+void Accessors::ScriptIdSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptIdInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ Handle<String> name(isolate->factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("id")));
+ return MakeAccessor(isolate,
+ name,
+ &ScriptIdGetter,
+ &ScriptIdSetter,
+ attributes);
+}
//
-// Accessors::ScriptId
+// Accessors::ScriptName
//
-MaybeObject* Accessors::ScriptGetId(Isolate* isolate, Object* object, void*) {
- Object* script = JSValue::cast(object)->value();
- return Script::cast(script)->id();
+void Accessors::ScriptNameGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ DisallowHeapAllocation no_allocation;
+ HandleScope scope(isolate);
+ Object* object = *Utils::OpenHandle(*info.This());
+ Object* source = Script::cast(JSValue::cast(object)->value())->name();
+ info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
}
-const AccessorDescriptor Accessors::ScriptId = {
- ScriptGetId,
- IllegalSetter,
- 0
-};
+void Accessors::ScriptNameSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptNameInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ return MakeAccessor(isolate,
+ isolate->factory()->name_string(),
+ &ScriptNameGetter,
+ &ScriptNameSetter,
+ attributes);
+}
//
-// Accessors::ScriptLineOffset
+// Accessors::ScriptSource
//
-MaybeObject* Accessors::ScriptGetLineOffset(Isolate* isolate,
- Object* object,
- void*) {
- Object* script = JSValue::cast(object)->value();
- return Script::cast(script)->line_offset();
+void Accessors::ScriptSourceGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ DisallowHeapAllocation no_allocation;
+ HandleScope scope(isolate);
+ Object* object = *Utils::OpenHandle(*info.This());
+ Object* source = Script::cast(JSValue::cast(object)->value())->source();
+ info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
}
-const AccessorDescriptor Accessors::ScriptLineOffset = {
- ScriptGetLineOffset,
- IllegalSetter,
- 0
-};
+void Accessors::ScriptSourceSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptSourceInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ return MakeAccessor(isolate,
+ isolate->factory()->source_string(),
+ &ScriptSourceGetter,
+ &ScriptSourceSetter,
+ attributes);
+}
//
-// Accessors::ScriptColumnOffset
+// Accessors::ScriptLineOffset
//
-MaybeObject* Accessors::ScriptGetColumnOffset(Isolate* isolate,
- Object* object,
- void*) {
- Object* script = JSValue::cast(object)->value();
- return Script::cast(script)->column_offset();
+void Accessors::ScriptLineOffsetGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ DisallowHeapAllocation no_allocation;
+ HandleScope scope(isolate);
+ Object* object = *Utils::OpenHandle(*info.This());
+ Object* res = Script::cast(JSValue::cast(object)->value())->line_offset();
+ info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
+}
+
+
+void Accessors::ScriptLineOffsetSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
}
-const AccessorDescriptor Accessors::ScriptColumnOffset = {
- ScriptGetColumnOffset,
- IllegalSetter,
- 0
-};
+Handle<AccessorInfo> Accessors::ScriptLineOffsetInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ Handle<String> name(isolate->factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("line_offset")));
+ return MakeAccessor(isolate,
+ name,
+ &ScriptLineOffsetGetter,
+ &ScriptLineOffsetSetter,
+ attributes);
+}
//
@@ -353,19 +447,36 @@ const AccessorDescriptor Accessors::ScriptColumnOffset = {
//
-MaybeObject* Accessors::ScriptGetType(Isolate* isolate,
- Object* object,
- void*) {
- Object* script = JSValue::cast(object)->value();
- return Script::cast(script)->type();
+void Accessors::ScriptTypeGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ DisallowHeapAllocation no_allocation;
+ HandleScope scope(isolate);
+ Object* object = *Utils::OpenHandle(*info.This());
+ Object* res = Script::cast(JSValue::cast(object)->value())->type();
+ info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
}
-const AccessorDescriptor Accessors::ScriptType = {
- ScriptGetType,
- IllegalSetter,
- 0
-};
+void Accessors::ScriptTypeSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptTypeInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ Handle<String> name(isolate->factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("type")));
+ return MakeAccessor(isolate,
+ name,
+ &ScriptTypeGetter,
+ &ScriptTypeSetter,
+ attributes);
+}
//
@@ -373,19 +484,37 @@ const AccessorDescriptor Accessors::ScriptType = {
//
-MaybeObject* Accessors::ScriptGetCompilationType(Isolate* isolate,
- Object* object,
- void*) {
- Object* script = JSValue::cast(object)->value();
- return Smi::FromInt(Script::cast(script)->compilation_type());
+void Accessors::ScriptCompilationTypeGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ DisallowHeapAllocation no_allocation;
+ HandleScope scope(isolate);
+ Object* object = *Utils::OpenHandle(*info.This());
+ Object* res = Smi::FromInt(
+ Script::cast(JSValue::cast(object)->value())->compilation_type());
+ info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
}
-const AccessorDescriptor Accessors::ScriptCompilationType = {
- ScriptGetCompilationType,
- IllegalSetter,
- 0
-};
+void Accessors::ScriptCompilationTypeSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptCompilationTypeInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ Handle<String> name(isolate->factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("compilation_type")));
+ return MakeAccessor(isolate,
+ name,
+ &ScriptCompilationTypeGetter,
+ &ScriptCompilationTypeSetter,
+ attributes);
+}
//
@@ -393,13 +522,15 @@ const AccessorDescriptor Accessors::ScriptCompilationType = {
//
-MaybeObject* Accessors::ScriptGetLineEnds(Isolate* isolate,
- Object* object,
- void*) {
- JSValue* wrapper = JSValue::cast(object);
+void Accessors::ScriptLineEndsGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
HandleScope scope(isolate);
- Handle<Script> script(Script::cast(wrapper->value()), isolate);
- InitScriptLineEnds(script);
+ Handle<Object> object = Utils::OpenHandle(*info.This());
+ Handle<Script> script(
+ Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
+ Script::InitLineEnds(script);
ASSERT(script->line_ends()->IsFixedArray());
Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
// We do not want anyone to modify this array from JS.
@@ -407,15 +538,28 @@ MaybeObject* Accessors::ScriptGetLineEnds(Isolate* isolate,
line_ends->map() == isolate->heap()->fixed_cow_array_map());
Handle<JSArray> js_array =
isolate->factory()->NewJSArrayWithElements(line_ends);
- return *js_array;
+ info.GetReturnValue().Set(Utils::ToLocal(js_array));
}
-const AccessorDescriptor Accessors::ScriptLineEnds = {
- ScriptGetLineEnds,
- IllegalSetter,
- 0
-};
+void Accessors::ScriptLineEndsSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptLineEndsInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ Handle<String> name(isolate->factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("line_ends")));
+ return MakeAccessor(isolate,
+ name,
+ &ScriptLineEndsGetter,
+ &ScriptLineEndsSetter,
+ attributes);
+}
//
@@ -423,19 +567,36 @@ const AccessorDescriptor Accessors::ScriptLineEnds = {
//
-MaybeObject* Accessors::ScriptGetContextData(Isolate* isolate,
- Object* object,
- void*) {
- Object* script = JSValue::cast(object)->value();
- return Script::cast(script)->context_data();
+void Accessors::ScriptContextDataGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ DisallowHeapAllocation no_allocation;
+ HandleScope scope(isolate);
+ Object* object = *Utils::OpenHandle(*info.This());
+ Object* res = Script::cast(JSValue::cast(object)->value())->context_data();
+ info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
+}
+
+
+void Accessors::ScriptContextDataSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
}
-const AccessorDescriptor Accessors::ScriptContextData = {
- ScriptGetContextData,
- IllegalSetter,
- 0
-};
+Handle<AccessorInfo> Accessors::ScriptContextDataInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ Handle<String> name(isolate->factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("context_data")));
+ return MakeAccessor(isolate,
+ name,
+ &ScriptContextDataGetter,
+ &ScriptContextDataSetter,
+ attributes);
+}
//
@@ -443,28 +604,46 @@ const AccessorDescriptor Accessors::ScriptContextData = {
//
-MaybeObject* Accessors::ScriptGetEvalFromScript(Isolate* isolate,
- Object* object,
- void*) {
- Object* script = JSValue::cast(object)->value();
- if (!Script::cast(script)->eval_from_shared()->IsUndefined()) {
+void Accessors::ScriptEvalFromScriptGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ HandleScope scope(isolate);
+ Handle<Object> object = Utils::OpenHandle(*info.This());
+ Handle<Script> script(
+ Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
+ Handle<Object> result = isolate->factory()->undefined_value();
+ if (!script->eval_from_shared()->IsUndefined()) {
Handle<SharedFunctionInfo> eval_from_shared(
- SharedFunctionInfo::cast(Script::cast(script)->eval_from_shared()));
-
+ SharedFunctionInfo::cast(script->eval_from_shared()));
if (eval_from_shared->script()->IsScript()) {
Handle<Script> eval_from_script(Script::cast(eval_from_shared->script()));
- return *GetScriptWrapper(eval_from_script);
+ result = Script::GetWrapper(eval_from_script);
}
}
- return isolate->heap()->undefined_value();
+
+ info.GetReturnValue().Set(Utils::ToLocal(result));
}
-const AccessorDescriptor Accessors::ScriptEvalFromScript = {
- ScriptGetEvalFromScript,
- IllegalSetter,
- 0
-};
+void Accessors::ScriptEvalFromScriptSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptEvalFromScriptInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ Handle<String> name(isolate->factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("eval_from_script")));
+ return MakeAccessor(isolate,
+ name,
+ &ScriptEvalFromScriptGetter,
+ &ScriptEvalFromScriptSetter,
+ attributes);
+}
//
@@ -472,32 +651,45 @@ const AccessorDescriptor Accessors::ScriptEvalFromScript = {
//
-MaybeObject* Accessors::ScriptGetEvalFromScriptPosition(Isolate* isolate,
- Object* object,
- void*) {
- Script* raw_script = Script::cast(JSValue::cast(object)->value());
+void Accessors::ScriptEvalFromScriptPositionGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
HandleScope scope(isolate);
- Handle<Script> script(raw_script);
-
- // If this is not a script compiled through eval there is no eval position.
- if (script->compilation_type() != Script::COMPILATION_TYPE_EVAL) {
- return script->GetHeap()->undefined_value();
+ Handle<Object> object = Utils::OpenHandle(*info.This());
+ Handle<Script> script(
+ Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
+ Handle<Object> result = isolate->factory()->undefined_value();
+ if (script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
+ Handle<Code> code(SharedFunctionInfo::cast(
+ script->eval_from_shared())->code());
+ result = Handle<Object>(
+ Smi::FromInt(code->SourcePosition(code->instruction_start() +
+ script->eval_from_instructions_offset()->value())),
+ isolate);
}
+ info.GetReturnValue().Set(Utils::ToLocal(result));
+}
- // Get the function from where eval was called and find the source position
- // from the instruction offset.
- Handle<Code> code(SharedFunctionInfo::cast(
- script->eval_from_shared())->code());
- return Smi::FromInt(code->SourcePosition(code->instruction_start() +
- script->eval_from_instructions_offset()->value()));
+
+void Accessors::ScriptEvalFromScriptPositionSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
}
-const AccessorDescriptor Accessors::ScriptEvalFromScriptPosition = {
- ScriptGetEvalFromScriptPosition,
- IllegalSetter,
- 0
-};
+Handle<AccessorInfo> Accessors::ScriptEvalFromScriptPositionInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ Handle<String> name(isolate->factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("eval_from_script_position")));
+ return MakeAccessor(isolate,
+ name,
+ &ScriptEvalFromScriptPositionGetter,
+ &ScriptEvalFromScriptPositionSetter,
+ attributes);
+}
//
@@ -505,100 +697,96 @@ const AccessorDescriptor Accessors::ScriptEvalFromScriptPosition = {
//
-MaybeObject* Accessors::ScriptGetEvalFromFunctionName(Isolate* isolate,
- Object* object,
- void*) {
- Object* script = JSValue::cast(object)->value();
- Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(
- Script::cast(script)->eval_from_shared()));
-
-
+void Accessors::ScriptEvalFromFunctionNameGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ HandleScope scope(isolate);
+ Handle<Object> object = Utils::OpenHandle(*info.This());
+ Handle<Script> script(
+ Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
+ Handle<Object> result;
+ Handle<SharedFunctionInfo> shared(
+ SharedFunctionInfo::cast(script->eval_from_shared()));
// Find the name of the function calling eval.
if (!shared->name()->IsUndefined()) {
- return shared->name();
+ result = Handle<Object>(shared->name(), isolate);
} else {
- return shared->inferred_name();
+ result = Handle<Object>(shared->inferred_name(), isolate);
}
+ info.GetReturnValue().Set(Utils::ToLocal(result));
}
-const AccessorDescriptor Accessors::ScriptEvalFromFunctionName = {
- ScriptGetEvalFromFunctionName,
- IllegalSetter,
- 0
-};
+void Accessors::ScriptEvalFromFunctionNameSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {
+ UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptEvalFromFunctionNameInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ Handle<String> name(isolate->factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("eval_from_function_name")));
+ return MakeAccessor(isolate,
+ name,
+ &ScriptEvalFromFunctionNameGetter,
+ &ScriptEvalFromFunctionNameSetter,
+ attributes);
+}
//
// Accessors::FunctionPrototype
//
+static Handle<Object> GetFunctionPrototype(Isolate* isolate,
+ Handle<Object> receiver) {
+ Handle<JSFunction> function;
+ {
+ DisallowHeapAllocation no_allocation;
+ JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, *receiver);
+ if (function_raw == NULL) return isolate->factory()->undefined_value();
+ while (!function_raw->should_have_prototype()) {
+ function_raw = FindInstanceOf<JSFunction>(isolate,
+ function_raw->GetPrototype());
+ // There has to be one because we hit the getter.
+ ASSERT(function_raw != NULL);
+ }
+ function = Handle<JSFunction>(function_raw, isolate);
+ }
-Handle<Object> Accessors::FunctionGetPrototype(Handle<JSFunction> function) {
- CALL_HEAP_FUNCTION(function->GetIsolate(),
- Accessors::FunctionGetPrototype(function->GetIsolate(),
- *function,
- NULL),
- Object);
-}
-
-
-Handle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
- Handle<Object> prototype) {
- ASSERT(function->should_have_prototype());
- CALL_HEAP_FUNCTION(function->GetIsolate(),
- Accessors::FunctionSetPrototype(function->GetIsolate(),
- *function,
- *prototype,
- NULL),
- Object);
-}
-
-
-MaybeObject* Accessors::FunctionGetPrototype(Isolate* isolate,
- Object* object,
- void*) {
- JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, object);
- if (function_raw == NULL) return isolate->heap()->undefined_value();
- while (!function_raw->should_have_prototype()) {
- function_raw = FindInstanceOf<JSFunction>(isolate,
- function_raw->GetPrototype());
- // There has to be one because we hit the getter.
- ASSERT(function_raw != NULL);
- }
-
- if (!function_raw->has_prototype()) {
- HandleScope scope(isolate);
- Handle<JSFunction> function(function_raw);
+ if (!function->has_prototype()) {
Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function);
JSFunction::SetPrototype(function, proto);
- function_raw = *function;
}
- return function_raw->prototype();
+ return Handle<Object>(function->prototype(), isolate);
}
-MaybeObject* Accessors::FunctionSetPrototype(Isolate* isolate,
- JSObject* object_raw,
- Object* value_raw,
- void*) {
- JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, object_raw);
- if (function_raw == NULL) return isolate->heap()->undefined_value();
+static Handle<Object> SetFunctionPrototype(Isolate* isolate,
+ Handle<JSObject> receiver,
+ Handle<Object> value) {
+ Handle<JSFunction> function;
+ {
+ DisallowHeapAllocation no_allocation;
+ JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, *receiver);
+ if (function_raw == NULL) return isolate->factory()->undefined_value();
+ function = Handle<JSFunction>(function_raw, isolate);
+ }
- HandleScope scope(isolate);
- Handle<JSFunction> function(function_raw, isolate);
- Handle<JSObject> object(object_raw, isolate);
- Handle<Object> value(value_raw, isolate);
if (!function->should_have_prototype()) {
// Since we hit this accessor, object will have no prototype property.
- Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(object,
- isolate->factory()->prototype_string(), value, NONE);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
- return *result;
+ MaybeHandle<Object> maybe_result =
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ receiver, isolate->factory()->prototype_string(), value, NONE);
+ return maybe_result.ToHandleChecked();
}
Handle<Object> old_value;
- bool is_observed = *function == *object && function->map()->is_observed();
+ bool is_observed = *function == *receiver && function->map()->is_observed();
if (is_observed) {
if (function->has_prototype())
old_value = handle(function->prototype(), isolate);
@@ -614,15 +802,56 @@ MaybeObject* Accessors::FunctionSetPrototype(Isolate* isolate,
function, "update", isolate->factory()->prototype_string(), old_value);
}
- return *function;
+ return function;
}
-const AccessorDescriptor Accessors::FunctionPrototype = {
- FunctionGetPrototype,
- FunctionSetPrototype,
- 0
-};
+Handle<Object> Accessors::FunctionGetPrototype(Handle<JSFunction> function) {
+ return GetFunctionPrototype(function->GetIsolate(), function);
+}
+
+
+Handle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
+ Handle<Object> prototype) {
+ ASSERT(function->should_have_prototype());
+ Isolate* isolate = function->GetIsolate();
+ return SetFunctionPrototype(isolate, function, prototype);
+}
+
+
+void Accessors::FunctionPrototypeGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ HandleScope scope(isolate);
+ Handle<Object> object = Utils::OpenHandle(*info.This());
+ Handle<Object> result = GetFunctionPrototype(isolate, object);
+ info.GetReturnValue().Set(Utils::ToLocal(result));
+}
+
+
+void Accessors::FunctionPrototypeSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> val,
+ const v8::PropertyCallbackInfo<void>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ HandleScope scope(isolate);
+ Handle<JSObject> object =
+ Handle<JSObject>::cast(Utils::OpenHandle(*info.This()));
+ Handle<Object> value = Utils::OpenHandle(*val);
+
+ SetFunctionPrototype(isolate, object, value);
+}
+
+
+Handle<AccessorInfo> Accessors::FunctionPrototypeInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ return MakeAccessor(isolate,
+ isolate->factory()->prototype_string(),
+ &FunctionPrototypeGetter,
+ &FunctionPrototypeSetter,
+ attributes);
+}
//
@@ -630,31 +859,57 @@ const AccessorDescriptor Accessors::FunctionPrototype = {
//
-MaybeObject* Accessors::FunctionGetLength(Isolate* isolate,
- Object* object,
- void*) {
- JSFunction* function = FindInstanceOf<JSFunction>(isolate, object);
- if (function == NULL) return Smi::FromInt(0);
- // Check if already compiled.
- if (function->shared()->is_compiled()) {
- return Smi::FromInt(function->shared()->length());
- }
- // If the function isn't compiled yet, the length is not computed correctly
- // yet. Compile it now and return the right length.
+void Accessors::FunctionLengthGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
HandleScope scope(isolate);
- Handle<JSFunction> function_handle(function);
- if (Compiler::EnsureCompiled(function_handle, KEEP_EXCEPTION)) {
- return Smi::FromInt(function_handle->shared()->length());
+ Handle<Object> object = Utils::OpenHandle(*info.This());
+ MaybeHandle<JSFunction> maybe_function;
+
+ {
+ DisallowHeapAllocation no_allocation;
+ JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object);
+ if (function != NULL) maybe_function = Handle<JSFunction>(function);
}
- return Failure::Exception();
+
+ int length = 0;
+ Handle<JSFunction> function;
+ if (maybe_function.ToHandle(&function)) {
+ if (function->shared()->is_compiled()) {
+ length = function->shared()->length();
+ } else {
+ // If the function isn't compiled yet, the length is not computed
+ // correctly yet. Compile it now and return the right length.
+ if (Compiler::EnsureCompiled(function, KEEP_EXCEPTION)) {
+ length = function->shared()->length();
+ }
+ if (isolate->has_pending_exception()) {
+ isolate->OptionalRescheduleException(false);
+ }
+ }
+ }
+ Handle<Object> result(Smi::FromInt(length), isolate);
+ info.GetReturnValue().Set(Utils::ToLocal(result));
}
-const AccessorDescriptor Accessors::FunctionLength = {
- FunctionGetLength,
- ReadOnlySetAccessor,
- 0
-};
+void Accessors::FunctionLengthSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> val,
+ const v8::PropertyCallbackInfo<void>& info) {
+ // Do nothing.
+}
+
+
+Handle<AccessorInfo> Accessors::FunctionLengthInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ return MakeAccessor(isolate,
+ isolate->factory()->length_string(),
+ &FunctionLengthGetter,
+ &FunctionLengthSetter,
+ attributes);
+}
//
@@ -662,21 +917,47 @@ const AccessorDescriptor Accessors::FunctionLength = {
//
-MaybeObject* Accessors::FunctionGetName(Isolate* isolate,
- Object* object,
- void*) {
- JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
- return holder == NULL
- ? isolate->heap()->undefined_value()
- : holder->shared()->name();
+void Accessors::FunctionNameGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ HandleScope scope(isolate);
+ Handle<Object> object = Utils::OpenHandle(*info.This());
+ MaybeHandle<JSFunction> maybe_function;
+
+ {
+ DisallowHeapAllocation no_allocation;
+ JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object);
+ if (function != NULL) maybe_function = Handle<JSFunction>(function);
+ }
+
+ Handle<JSFunction> function;
+ Handle<Object> result;
+ if (maybe_function.ToHandle(&function)) {
+ result = Handle<Object>(function->shared()->name(), isolate);
+ } else {
+ result = isolate->factory()->undefined_value();
+ }
+ info.GetReturnValue().Set(Utils::ToLocal(result));
}
-const AccessorDescriptor Accessors::FunctionName = {
- FunctionGetName,
- ReadOnlySetAccessor,
- 0
-};
+void Accessors::FunctionNameSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> val,
+ const v8::PropertyCallbackInfo<void>& info) {
+ // Do nothing.
+}
+
+
+Handle<AccessorInfo> Accessors::FunctionNameInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ return MakeAccessor(isolate,
+ isolate->factory()->name_string(),
+ &FunctionNameGetter,
+ &FunctionNameSetter,
+ attributes);
+}
//
@@ -684,16 +965,7 @@ const AccessorDescriptor Accessors::FunctionName = {
//
-Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
- CALL_HEAP_FUNCTION(function->GetIsolate(),
- Accessors::FunctionGetArguments(function->GetIsolate(),
- *function,
- NULL),
- Object);
-}
-
-
-static MaybeObject* ConstructArgumentsObjectForInlinedFunction(
+static Handle<Object> ArgumentsForInlinedFunction(
JavaScriptFrame* frame,
Handle<JSFunction> inlined_function,
int inlined_frame_index) {
@@ -717,81 +989,124 @@ static MaybeObject* ConstructArgumentsObjectForInlinedFunction(
arguments->set_elements(*array);
// Return the freshly allocated arguments object.
- return *arguments;
+ return arguments;
}
-MaybeObject* Accessors::FunctionGetArguments(Isolate* isolate,
- Object* object,
- void*) {
- HandleScope scope(isolate);
- JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
- if (holder == NULL) return isolate->heap()->undefined_value();
- Handle<JSFunction> function(holder, isolate);
+static int FindFunctionInFrame(JavaScriptFrame* frame,
+ Handle<JSFunction> function) {
+ DisallowHeapAllocation no_allocation;
+ List<JSFunction*> functions(2);
+ frame->GetFunctions(&functions);
+ for (int i = functions.length() - 1; i >= 0; i--) {
+ if (functions[i] == *function) return i;
+ }
+ return -1;
+}
+
+
+Handle<Object> GetFunctionArguments(Isolate* isolate,
+ Handle<JSFunction> function) {
+ if (function->shared()->native()) return isolate->factory()->null_value();
- if (function->shared()->native()) return isolate->heap()->null_value();
// Find the top invocation of the function by traversing frames.
- List<JSFunction*> functions(2);
for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
JavaScriptFrame* frame = it.frame();
- frame->GetFunctions(&functions);
- for (int i = functions.length() - 1; i >= 0; i--) {
- // Skip all frames that aren't invocations of the given function.
- if (functions[i] != *function) continue;
-
- if (i > 0) {
- // The function in question was inlined. Inlined functions have the
- // correct number of arguments and no allocated arguments object, so
- // we can construct a fresh one by interpreting the function's
- // deoptimization input data.
- return ConstructArgumentsObjectForInlinedFunction(frame, function, i);
- }
+ int function_index = FindFunctionInFrame(frame, function);
+ if (function_index < 0) continue;
+
+ if (function_index > 0) {
+ // The function in question was inlined. Inlined functions have the
+ // correct number of arguments and no allocated arguments object, so
+ // we can construct a fresh one by interpreting the function's
+ // deoptimization input data.
+ return ArgumentsForInlinedFunction(frame, function, function_index);
+ }
- if (!frame->is_optimized()) {
- // If there is an arguments variable in the stack, we return that.
- Handle<ScopeInfo> scope_info(function->shared()->scope_info());
- int index = scope_info->StackSlotIndex(
- isolate->heap()->arguments_string());
- if (index >= 0) {
- Handle<Object> arguments(frame->GetExpression(index), isolate);
- if (!arguments->IsArgumentsMarker()) return *arguments;
- }
+ if (!frame->is_optimized()) {
+ // If there is an arguments variable in the stack, we return that.
+ Handle<ScopeInfo> scope_info(function->shared()->scope_info());
+ int index = scope_info->StackSlotIndex(
+ isolate->heap()->arguments_string());
+ if (index >= 0) {
+ Handle<Object> arguments(frame->GetExpression(index), isolate);
+ if (!arguments->IsArgumentsMarker()) return arguments;
}
-
- // If there is no arguments variable in the stack or we have an
- // optimized frame, we find the frame that holds the actual arguments
- // passed to the function.
- it.AdvanceToArgumentsFrame();
- frame = it.frame();
-
- // Get the number of arguments and construct an arguments object
- // mirror for the right frame.
- const int length = frame->ComputeParametersCount();
- Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
- function, length);
- Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
-
- // Copy the parameters to the arguments object.
- ASSERT(array->length() == length);
- for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
- arguments->set_elements(*array);
-
- // Return the freshly allocated arguments object.
- return *arguments;
}
- functions.Rewind(0);
+
+ // If there is no arguments variable in the stack or we have an
+ // optimized frame, we find the frame that holds the actual arguments
+ // passed to the function.
+ it.AdvanceToArgumentsFrame();
+ frame = it.frame();
+
+ // Get the number of arguments and construct an arguments object
+ // mirror for the right frame.
+ const int length = frame->ComputeParametersCount();
+ Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
+ function, length);
+ Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
+
+ // Copy the parameters to the arguments object.
+ ASSERT(array->length() == length);
+ for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
+ arguments->set_elements(*array);
+
+ // Return the freshly allocated arguments object.
+ return arguments;
}
// No frame corresponding to the given function found. Return null.
- return isolate->heap()->null_value();
+ return isolate->factory()->null_value();
}
-const AccessorDescriptor Accessors::FunctionArguments = {
- FunctionGetArguments,
- ReadOnlySetAccessor,
- 0
-};
+Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
+ return GetFunctionArguments(function->GetIsolate(), function);
+}
+
+
+void Accessors::FunctionArgumentsGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ HandleScope scope(isolate);
+ Handle<Object> object = Utils::OpenHandle(*info.This());
+ MaybeHandle<JSFunction> maybe_function;
+
+ {
+ DisallowHeapAllocation no_allocation;
+ JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object);
+ if (function != NULL) maybe_function = Handle<JSFunction>(function);
+ }
+
+ Handle<JSFunction> function;
+ Handle<Object> result;
+ if (maybe_function.ToHandle(&function)) {
+ result = GetFunctionArguments(isolate, function);
+ } else {
+ result = isolate->factory()->undefined_value();
+ }
+ info.GetReturnValue().Set(Utils::ToLocal(result));
+}
+
+
+void Accessors::FunctionArgumentsSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> val,
+ const v8::PropertyCallbackInfo<void>& info) {
+ // Do nothing.
+}
+
+
+Handle<AccessorInfo> Accessors::FunctionArgumentsInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ return MakeAccessor(isolate,
+ isolate->factory()->arguments_string(),
+ &FunctionArgumentsGetter,
+ &FunctionArgumentsSetter,
+ attributes);
+}
//
@@ -845,29 +1160,23 @@ class FrameFunctionIterator {
};
-MaybeObject* Accessors::FunctionGetCaller(Isolate* isolate,
- Object* object,
- void*) {
- HandleScope scope(isolate);
+MaybeHandle<JSFunction> FindCaller(Isolate* isolate,
+ Handle<JSFunction> function) {
DisallowHeapAllocation no_allocation;
- JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
- if (holder == NULL) return isolate->heap()->undefined_value();
- if (holder->shared()->native()) return isolate->heap()->null_value();
- Handle<JSFunction> function(holder, isolate);
-
FrameFunctionIterator it(isolate, no_allocation);
-
+ if (function->shared()->native()) {
+ return MaybeHandle<JSFunction>();
+ }
// Find the function from the frames.
if (!it.Find(*function)) {
// No frame corresponding to the given function found. Return null.
- return isolate->heap()->null_value();
+ return MaybeHandle<JSFunction>();
}
-
// Find previously called non-toplevel function.
JSFunction* caller;
do {
caller = it.next();
- if (caller == NULL) return isolate->heap()->null_value();
+ if (caller == NULL) return MaybeHandle<JSFunction>();
} while (caller->shared()->is_toplevel());
// If caller is a built-in function and caller's caller is also built-in,
@@ -884,24 +1193,64 @@ MaybeObject* Accessors::FunctionGetCaller(Isolate* isolate,
// allows us to make bound functions use the strict function map
// and its associated throwing caller and arguments.
if (caller->shared()->bound()) {
- return isolate->heap()->null_value();
+ return MaybeHandle<JSFunction>();
}
// Censor if the caller is not a sloppy mode function.
// Change from ES5, which used to throw, see:
// https://bugs.ecmascript.org/show_bug.cgi?id=310
if (caller->shared()->strict_mode() == STRICT) {
- return isolate->heap()->null_value();
+ return MaybeHandle<JSFunction>();
+ }
+ return Handle<JSFunction>(caller);
+}
+
+
+void Accessors::FunctionCallerGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+ HandleScope scope(isolate);
+ Handle<Object> object = Utils::OpenHandle(*info.This());
+ MaybeHandle<JSFunction> maybe_function;
+ {
+ DisallowHeapAllocation no_allocation;
+ JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object);
+ if (function != NULL) maybe_function = Handle<JSFunction>(function);
+ }
+ Handle<JSFunction> function;
+ Handle<Object> result;
+ if (maybe_function.ToHandle(&function)) {
+ MaybeHandle<JSFunction> maybe_caller;
+ maybe_caller = FindCaller(isolate, function);
+ Handle<JSFunction> caller;
+ if (maybe_caller.ToHandle(&caller)) {
+ result = caller;
+ } else {
+ result = isolate->factory()->null_value();
+ }
+ } else {
+ result = isolate->factory()->undefined_value();
}
+ info.GetReturnValue().Set(Utils::ToLocal(result));
+}
+
- return caller;
+void Accessors::FunctionCallerSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> val,
+ const v8::PropertyCallbackInfo<void>& info) {
+ // Do nothing.
}
-const AccessorDescriptor Accessors::FunctionCaller = {
- FunctionGetCaller,
- ReadOnlySetAccessor,
- 0
-};
+Handle<AccessorInfo> Accessors::FunctionCallerInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ return MakeAccessor(isolate,
+ isolate->factory()->caller_string(),
+ &FunctionCallerGetter,
+ &FunctionCallerSetter,
+ attributes);
+}
//
diff --git a/deps/v8/src/accessors.h b/deps/v8/src/accessors.h
index 83a847222b..8c006e93ac 100644
--- a/deps/v8/src/accessors.h
+++ b/deps/v8/src/accessors.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ACCESSORS_H_
#define V8_ACCESSORS_H_
@@ -36,42 +13,52 @@ namespace internal {
// The list of accessor descriptors. This is a second-order macro
// taking a macro to be applied to all accessor descriptor names.
-#define ACCESSOR_DESCRIPTOR_LIST(V) \
- V(FunctionPrototype) \
- V(FunctionLength) \
- V(FunctionName) \
+#define ACCESSOR_INFO_LIST(V) \
+ V(ArrayLength) \
V(FunctionArguments) \
V(FunctionCaller) \
- V(ArrayLength) \
- V(StringLength) \
- V(ScriptSource) \
- V(ScriptName) \
- V(ScriptId) \
- V(ScriptLineOffset) \
+ V(FunctionName) \
+ V(FunctionLength) \
+ V(FunctionPrototype) \
V(ScriptColumnOffset) \
- V(ScriptType) \
V(ScriptCompilationType) \
- V(ScriptLineEnds) \
V(ScriptContextData) \
V(ScriptEvalFromScript) \
V(ScriptEvalFromScriptPosition) \
- V(ScriptEvalFromFunctionName)
+ V(ScriptEvalFromFunctionName) \
+ V(ScriptId) \
+ V(ScriptLineEnds) \
+ V(ScriptLineOffset) \
+ V(ScriptName) \
+ V(ScriptSource) \
+ V(ScriptType) \
+ V(StringLength)
// Accessors contains all predefined proxy accessors.
class Accessors : public AllStatic {
public:
// Accessor descriptors.
-#define ACCESSOR_DESCRIPTOR_DECLARATION(name) \
- static const AccessorDescriptor name;
- ACCESSOR_DESCRIPTOR_LIST(ACCESSOR_DESCRIPTOR_DECLARATION)
-#undef ACCESSOR_DESCRIPTOR_DECLARATION
+#define ACCESSOR_INFO_DECLARATION(name) \
+ static void name##Getter( \
+ v8::Local<v8::String> name, \
+ const v8::PropertyCallbackInfo<v8::Value>& info); \
+ static void name##Setter( \
+ v8::Local<v8::String> name, \
+ v8::Local<v8::Value> value, \
+ const v8::PropertyCallbackInfo<void>& info); \
+ static Handle<AccessorInfo> name##Info( \
+ Isolate* isolate, \
+ PropertyAttributes attributes);
+ ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION)
+#undef ACCESSOR_INFO_DECLARATION
enum DescriptorId {
-#define ACCESSOR_DESCRIPTOR_DECLARATION(name) \
- k##name,
- ACCESSOR_DESCRIPTOR_LIST(ACCESSOR_DESCRIPTOR_DECLARATION)
-#undef ACCESSOR_DESCRIPTOR_DECLARATION
+#define ACCESSOR_INFO_DECLARATION(name) \
+ k##name##Getter, \
+ k##name##Setter,
+ ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION)
+#undef ACCESSOR_INFO_DECLARATION
descriptorCount
};
@@ -92,72 +79,16 @@ class Accessors : public AllStatic {
Handle<String> name,
int* object_offset);
+ static Handle<AccessorInfo> MakeAccessor(
+ Isolate* isolate,
+ Handle<String> name,
+ AccessorGetterCallback getter,
+ AccessorSetterCallback setter,
+ PropertyAttributes attributes);
private:
- // Accessor functions only used through the descriptor.
- static MaybeObject* FunctionSetPrototype(Isolate* isolate,
- JSObject* object,
- Object*,
- void*);
- static MaybeObject* FunctionGetPrototype(Isolate* isolate,
- Object* object,
- void*);
- static MaybeObject* FunctionGetLength(Isolate* isolate,
- Object* object,
- void*);
- static MaybeObject* FunctionGetName(Isolate* isolate, Object* object, void*);
- static MaybeObject* FunctionGetArguments(Isolate* isolate,
- Object* object,
- void*);
- static MaybeObject* FunctionGetCaller(Isolate* isolate,
- Object* object,
- void*);
- static MaybeObject* ArraySetLength(Isolate* isolate,
- JSObject* object,
- Object*,
- void*);
- static MaybeObject* ArrayGetLength(Isolate* isolate, Object* object, void*);
- static MaybeObject* StringGetLength(Isolate* isolate, Object* object, void*);
- static MaybeObject* ScriptGetName(Isolate* isolate, Object* object, void*);
- static MaybeObject* ScriptGetId(Isolate* isolate, Object* object, void*);
- static MaybeObject* ScriptGetSource(Isolate* isolate, Object* object, void*);
- static MaybeObject* ScriptGetLineOffset(Isolate* isolate,
- Object* object,
- void*);
- static MaybeObject* ScriptGetColumnOffset(Isolate* isolate,
- Object* object,
- void*);
- static MaybeObject* ScriptGetType(Isolate* isolate, Object* object, void*);
- static MaybeObject* ScriptGetCompilationType(Isolate* isolate,
- Object* object,
- void*);
- static MaybeObject* ScriptGetLineEnds(Isolate* isolate,
- Object* object,
- void*);
- static MaybeObject* ScriptGetContextData(Isolate* isolate,
- Object* object,
- void*);
- static MaybeObject* ScriptGetEvalFromScript(Isolate* isolate,
- Object* object,
- void*);
- static MaybeObject* ScriptGetEvalFromScriptPosition(Isolate* isolate,
- Object* object,
- void*);
- static MaybeObject* ScriptGetEvalFromFunctionName(Isolate* isolate,
- Object* object,
- void*);
-
// Helper functions.
static Handle<Object> FlattenNumber(Isolate* isolate, Handle<Object> value);
- static MaybeObject* IllegalSetter(Isolate* isolate,
- JSObject*,
- Object*,
- void*);
- static Object* IllegalGetAccessor(Isolate* isolate, Object* object, void*);
- static MaybeObject* ReadOnlySetAccessor(Isolate* isolate,
- JSObject*,
- Object* value,
- void*);
};
} } // namespace v8::internal
diff --git a/deps/v8/src/allocation-site-scopes.cc b/deps/v8/src/allocation-site-scopes.cc
index bbfb39b122..51392fac8e 100644
--- a/deps/v8/src/allocation-site-scopes.cc
+++ b/deps/v8/src/allocation-site-scopes.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "allocation-site-scopes.h"
@@ -62,7 +39,7 @@ Handle<AllocationSite> AllocationSiteCreationContext::EnterNewScope() {
void AllocationSiteCreationContext::ExitScope(
Handle<AllocationSite> scope_site,
Handle<JSObject> object) {
- if (!object.is_null() && !object->IsFailure()) {
+ if (!object.is_null()) {
bool top_level = !scope_site.is_null() &&
top().is_identical_to(scope_site);
diff --git a/deps/v8/src/allocation-site-scopes.h b/deps/v8/src/allocation-site-scopes.h
index a195b27d85..1ffe004e1b 100644
--- a/deps/v8/src/allocation-site-scopes.h
+++ b/deps/v8/src/allocation-site-scopes.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ALLOCATION_SITE_SCOPES_H_
#define V8_ALLOCATION_SITE_SCOPES_H_
diff --git a/deps/v8/src/allocation-tracker.cc b/deps/v8/src/allocation-tracker.cc
index a9103a84a3..f5d7e0c9d4 100644
--- a/deps/v8/src/allocation-tracker.cc
+++ b/deps/v8/src/allocation-tracker.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -211,11 +188,6 @@ void AddressToTraceMap::RemoveRange(Address start, Address end) {
}
-static bool AddressesMatch(void* key1, void* key2) {
- return key1 == key2;
-}
-
-
void AllocationTracker::DeleteFunctionInfo(FunctionInfo** info) {
delete *info;
}
@@ -225,7 +197,7 @@ AllocationTracker::AllocationTracker(
HeapObjectsMap* ids, StringsStorage* names)
: ids_(ids),
names_(names),
- id_to_function_info_index_(AddressesMatch),
+ id_to_function_info_index_(HashMap::PointersMatch),
info_index_for_other_state_(0) {
FunctionInfo* info = new FunctionInfo();
info->name = "(root)";
@@ -354,8 +326,8 @@ AllocationTracker::UnresolvedLocation::~UnresolvedLocation() {
void AllocationTracker::UnresolvedLocation::Resolve() {
if (script_.is_null()) return;
HandleScope scope(script_->GetIsolate());
- info_->line = GetScriptLineNumber(script_, start_position_);
- info_->column = GetScriptColumnNumber(script_, start_position_);
+ info_->line = Script::GetLineNumber(script_, start_position_);
+ info_->column = Script::GetColumnNumber(script_, start_position_);
}
diff --git a/deps/v8/src/allocation-tracker.h b/deps/v8/src/allocation-tracker.h
index b876d7d14e..f3788b91a6 100644
--- a/deps/v8/src/allocation-tracker.h
+++ b/deps/v8/src/allocation-tracker.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ALLOCATION_TRACKER_H_
#define V8_ALLOCATION_TRACKER_H_
diff --git a/deps/v8/src/allocation.cc b/deps/v8/src/allocation.cc
index ff16dab3cc..0549a199ff 100644
--- a/deps/v8/src/allocation.cc
+++ b/deps/v8/src/allocation.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "allocation.h"
diff --git a/deps/v8/src/allocation.h b/deps/v8/src/allocation.h
index 380fa05ff3..13d08a8169 100644
--- a/deps/v8/src/allocation.h
+++ b/deps/v8/src/allocation.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ALLOCATION_H_
#define V8_ALLOCATION_H_
diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc
index 5dcf592296..8a99c278cb 100644
--- a/deps/v8/src/api.cc
+++ b/deps/v8/src/api.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "api.h"
@@ -106,7 +83,7 @@ namespace v8 {
#define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value) \
EXCEPTION_BAILOUT_CHECK_GENERIC( \
- isolate, value, i::V8::FireCallCompletedCallback(isolate);)
+ isolate, value, isolate->FireCallCompletedCallback();)
#define EXCEPTION_BAILOUT_CHECK(isolate, value) \
@@ -244,24 +221,6 @@ static inline bool EnsureInitializedForIsolate(i::Isolate* isolate,
}
-// Some initializing API functions are called early and may be
-// called on a thread different from static initializer thread.
-// If Isolate API is used, Isolate::Enter() will initialize TLS so
-// Isolate::Current() works. If it's a legacy case, then the thread
-// may not have TLS initialized yet. However, in initializing APIs it
-// may be too early to call EnsureInitialized() - some pre-init
-// parameters still have to be configured.
-static inline i::Isolate* EnterIsolateIfNeeded() {
- i::Isolate* isolate = i::Isolate::UncheckedCurrent();
- if (isolate != NULL)
- return isolate;
-
- i::Isolate::EnterDefaultIsolate();
- isolate = i::Isolate::Current();
- return isolate;
-}
-
-
StartupDataDecompressor::StartupDataDecompressor()
: raw_data(i::NewArray<char*>(V8::GetCompressedStartupDataCount())) {
for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
@@ -391,14 +350,14 @@ void V8::SetDecompressedStartupData(StartupData* decompressed_data) {
void V8::SetFatalErrorHandler(FatalErrorCallback that) {
- i::Isolate* isolate = EnterIsolateIfNeeded();
+ i::Isolate* isolate = i::Isolate::UncheckedCurrent();
isolate->set_exception_behavior(that);
}
void V8::SetAllowCodeGenerationFromStringsCallback(
AllowCodeGenerationFromStringsCallback callback) {
- i::Isolate* isolate = EnterIsolateIfNeeded();
+ i::Isolate* isolate = i::Isolate::UncheckedCurrent();
isolate->set_allow_code_gen_callback(callback);
}
@@ -460,15 +419,16 @@ Extension::Extension(const char* name,
ResourceConstraints::ResourceConstraints()
- : max_young_space_size_(0),
+ : max_new_space_size_(0),
max_old_space_size_(0),
max_executable_size_(0),
stack_limit_(NULL),
- max_available_threads_(0) { }
+ max_available_threads_(0),
+ code_range_size_(0) { }
void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
+ uint64_t virtual_memory_limit,
uint32_t number_of_processors) {
- const int lump_of_memory = (i::kPointerSize / 4) * i::MB;
#if V8_OS_ANDROID
// Android has higher physical memory requirements before raising the maximum
// heap size limits since it has no swap space.
@@ -481,42 +441,50 @@ void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
const uint64_t high_limit = 1ul * i::GB;
#endif
- // The young_space_size should be a power of 2 and old_generation_size should
- // be a multiple of Page::kPageSize.
if (physical_memory <= low_limit) {
- set_max_young_space_size(2 * lump_of_memory);
- set_max_old_space_size(128 * lump_of_memory);
- set_max_executable_size(96 * lump_of_memory);
+ set_max_new_space_size(i::Heap::kMaxNewSpaceSizeLowMemoryDevice);
+ set_max_old_space_size(i::Heap::kMaxOldSpaceSizeLowMemoryDevice);
+ set_max_executable_size(i::Heap::kMaxExecutableSizeLowMemoryDevice);
} else if (physical_memory <= medium_limit) {
- set_max_young_space_size(8 * lump_of_memory);
- set_max_old_space_size(256 * lump_of_memory);
- set_max_executable_size(192 * lump_of_memory);
+ set_max_new_space_size(i::Heap::kMaxNewSpaceSizeMediumMemoryDevice);
+ set_max_old_space_size(i::Heap::kMaxOldSpaceSizeMediumMemoryDevice);
+ set_max_executable_size(i::Heap::kMaxExecutableSizeMediumMemoryDevice);
} else if (physical_memory <= high_limit) {
- set_max_young_space_size(16 * lump_of_memory);
- set_max_old_space_size(512 * lump_of_memory);
- set_max_executable_size(256 * lump_of_memory);
+ set_max_new_space_size(i::Heap::kMaxNewSpaceSizeHighMemoryDevice);
+ set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHighMemoryDevice);
+ set_max_executable_size(i::Heap::kMaxExecutableSizeHighMemoryDevice);
} else {
- set_max_young_space_size(16 * lump_of_memory);
- set_max_old_space_size(700 * lump_of_memory);
- set_max_executable_size(256 * lump_of_memory);
+ set_max_new_space_size(i::Heap::kMaxNewSpaceSizeHugeMemoryDevice);
+ set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHugeMemoryDevice);
+ set_max_executable_size(i::Heap::kMaxExecutableSizeHugeMemoryDevice);
}
set_max_available_threads(i::Max(i::Min(number_of_processors, 4u), 1u));
+
+ if (virtual_memory_limit > 0 && i::kIs64BitArch) {
+ // Reserve no more than 1/8 of the memory for the code range, but at most
+ // 512 MB.
+ set_code_range_size(
+ i::Min(512 * i::MB, static_cast<int>(virtual_memory_limit >> 3)));
+ }
}
bool SetResourceConstraints(Isolate* v8_isolate,
ResourceConstraints* constraints) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- int young_space_size = constraints->max_young_space_size();
- int old_gen_size = constraints->max_old_space_size();
+ int new_space_size = constraints->max_new_space_size();
+ int old_space_size = constraints->max_old_space_size();
int max_executable_size = constraints->max_executable_size();
- if (young_space_size != 0 || old_gen_size != 0 || max_executable_size != 0) {
+ int code_range_size = constraints->code_range_size();
+ if (new_space_size != 0 || old_space_size != 0 || max_executable_size != 0 ||
+ code_range_size != 0) {
// After initialization it's too late to change Heap constraints.
ASSERT(!isolate->IsInitialized());
- bool result = isolate->heap()->ConfigureHeap(young_space_size / 2,
- old_gen_size,
- max_executable_size);
+ bool result = isolate->heap()->ConfigureHeap(new_space_size / 2,
+ old_space_size,
+ max_executable_size,
+ code_range_size);
if (!result) return false;
}
if (constraints->stack_limit() != NULL) {
@@ -533,7 +501,7 @@ i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
LOG_API(isolate, "Persistent::New");
i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
#ifdef DEBUG
- (*obj)->Verify();
+ (*obj)->ObjectVerify();
#endif // DEBUG
return result.location();
}
@@ -542,7 +510,7 @@ i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
i::Object** V8::CopyPersistent(i::Object** obj) {
i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
#ifdef DEBUG
- (*obj)->Verify();
+ (*obj)->ObjectVerify();
#endif // DEBUG
return result.location();
}
@@ -703,7 +671,7 @@ static i::Handle<i::FixedArray> EmbedderDataFor(Context* context,
return i::Handle<i::FixedArray>();
}
int new_size = i::Max(index, data->length() << 1) + 1;
- data = env->GetIsolate()->factory()->CopySizeFixedArray(data, new_size);
+ data = i::FixedArray::CopySize(data, new_size);
env->set_embedder_data(*data);
return data;
}
@@ -1567,45 +1535,6 @@ void ObjectTemplate::SetInternalFieldCount(int value) {
}
-// --- S c r i p t D a t a ---
-
-
-ScriptData* ScriptData::PreCompile(v8::Handle<String> source) {
- i::Handle<i::String> str = Utils::OpenHandle(*source);
- i::Isolate* isolate = str->GetIsolate();
- if (str->IsExternalTwoByteString()) {
- i::ExternalTwoByteStringUtf16CharacterStream stream(
- i::Handle<i::ExternalTwoByteString>::cast(str), 0, str->length());
- return i::PreParserApi::PreParse(isolate, &stream);
- } else {
- i::GenericStringUtf16CharacterStream stream(str, 0, str->length());
- return i::PreParserApi::PreParse(isolate, &stream);
- }
-}
-
-
-ScriptData* ScriptData::New(const char* data, int length) {
- // Return an empty ScriptData if the length is obviously invalid.
- if (length % sizeof(unsigned) != 0) {
- return new i::ScriptDataImpl();
- }
-
- // Copy the data to ensure it is properly aligned.
- int deserialized_data_length = length / sizeof(unsigned);
- // If aligned, don't create a copy of the data.
- if (reinterpret_cast<intptr_t>(data) % sizeof(unsigned) == 0) {
- return new i::ScriptDataImpl(data, length);
- }
- // Copy the data to align it.
- unsigned* deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
- i::CopyBytes(reinterpret_cast<char*>(deserialized_data),
- data, static_cast<size_t>(length));
-
- return new i::ScriptDataImpl(
- i::Vector<unsigned>(deserialized_data, deserialized_data_length));
-}
-
-
// --- S c r i p t s ---
@@ -1660,7 +1589,7 @@ int UnboundScript::GetLineNumber(int code_pos) {
LOG_API(isolate, "UnboundScript::GetLineNumber");
if (obj->IsScript()) {
i::Handle<i::Script> script(i::Script::cast(*obj));
- return i::GetScriptLineNumber(script, code_pos);
+ return i::Script::GetLineNumber(script, code_pos);
} else {
return -1;
}
@@ -1695,21 +1624,16 @@ Local<Value> Script::Run() {
ENTER_V8(isolate);
i::Logger::TimerEventScope timer_scope(
isolate, i::Logger::TimerEventScope::v8_execute);
- i::Object* raw_result = NULL;
- {
- i::HandleScope scope(isolate);
- i::Handle<i::JSFunction> fun =
- i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> receiver(
- isolate->context()->global_proxy(), isolate);
- i::Handle<i::Object> result = i::Execution::Call(
- isolate, fun, receiver, 0, NULL, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
- raw_result = *result;
- }
- i::Handle<i::Object> result(raw_result, isolate);
- return Utils::ToLocal(result);
+ i::HandleScope scope(isolate);
+ i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
+ EXCEPTION_PREAMBLE(isolate);
+ i::Handle<i::Object> receiver(
+ isolate->context()->global_proxy(), isolate);
+ i::Handle<i::Object> result;
+ has_pending_exception = !i::Execution::Call(
+ isolate, fun, receiver, 0, NULL).ToHandle(&result);
+ EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
+ return Utils::ToLocal(scope.CloseAndEscape(result));
}
@@ -1724,42 +1648,46 @@ Local<UnboundScript> ScriptCompiler::CompileUnbound(
Isolate* v8_isolate,
Source* source,
CompileOptions options) {
- i::ScriptDataImpl* script_data_impl = NULL;
+ i::ScriptData* script_data_impl = NULL;
i::CachedDataMode cached_data_mode = i::NO_CACHED_DATA;
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
+ ON_BAILOUT(isolate, "v8::ScriptCompiler::CompileUnbound()",
+ return Local<UnboundScript>());
if (options & kProduceDataToCache) {
cached_data_mode = i::PRODUCE_CACHED_DATA;
ASSERT(source->cached_data == NULL);
if (source->cached_data) {
// Asked to produce cached data even though there is some already -> not
- // good. In release mode, try to do the right thing: Just regenerate the
- // data.
- delete source->cached_data;
- source->cached_data = NULL;
+ // good. Fail the compilation.
+ EXCEPTION_PREAMBLE(isolate);
+ i::Handle<i::Object> result = isolate->factory()->NewSyntaxError(
+ "invalid_cached_data", isolate->factory()->NewJSArray(0));
+ isolate->Throw(*result);
+ isolate->ReportPendingMessages();
+ has_pending_exception = true;
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<UnboundScript>());
}
} else if (source->cached_data) {
- // FIXME(marja): Make compiler use CachedData directly. Aligning needs to be
- // taken care of.
- script_data_impl = static_cast<i::ScriptDataImpl*>(ScriptData::New(
+ cached_data_mode = i::CONSUME_CACHED_DATA;
+ // ScriptData takes care of aligning, in case the data is not aligned
+ // correctly.
+ script_data_impl = i::ScriptData::New(
reinterpret_cast<const char*>(source->cached_data->data),
- source->cached_data->length));
- // We assert that the pre-data is sane, even though we can actually
- // handle it if it turns out not to be in release mode.
- ASSERT(script_data_impl->SanityCheck());
- if (script_data_impl->SanityCheck()) {
- cached_data_mode = i::CONSUME_CACHED_DATA;
- } else {
- // If the pre-data isn't sane we simply ignore it.
+ source->cached_data->length);
+ // If the cached data is not valid, fail the compilation.
+ if (script_data_impl == NULL || !script_data_impl->SanityCheck()) {
+ EXCEPTION_PREAMBLE(isolate);
+ i::Handle<i::Object> result = isolate->factory()->NewSyntaxError(
+ "invalid_cached_data", isolate->factory()->NewJSArray(0));
+ isolate->Throw(*result);
+ isolate->ReportPendingMessages();
delete script_data_impl;
- script_data_impl = NULL;
- delete source->cached_data;
- source->cached_data = NULL;
+ has_pending_exception = true;
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<UnboundScript>());
}
}
i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string));
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- ON_BAILOUT(isolate, "v8::ScriptCompiler::CompileUnbound()",
- return Local<UnboundScript>());
LOG_API(isolate, "ScriptCompiler::CompileUnbound");
ENTER_V8(isolate);
i::SharedFunctionInfo* raw_result = NULL;
@@ -1830,22 +1758,15 @@ Local<Script> ScriptCompiler::Compile(
Local<Script> Script::Compile(v8::Handle<String> source,
- v8::ScriptOrigin* origin,
- ScriptData* script_data) {
+ v8::ScriptOrigin* origin) {
i::Handle<i::String> str = Utils::OpenHandle(*source);
- ScriptCompiler::CachedData* cached_data = NULL;
- if (script_data) {
- cached_data = new ScriptCompiler::CachedData(
- reinterpret_cast<const uint8_t*>(script_data->Data()),
- script_data->Length());
- }
if (origin) {
- ScriptCompiler::Source script_source(source, *origin, cached_data);
+ ScriptCompiler::Source script_source(source, *origin);
return ScriptCompiler::Compile(
reinterpret_cast<v8::Isolate*>(str->GetIsolate()),
&script_source);
}
- ScriptCompiler::Source script_source(source, cached_data);
+ ScriptCompiler::Source script_source(source);
return ScriptCompiler::Compile(
reinterpret_cast<v8::Isolate*>(str->GetIsolate()),
&script_source);
@@ -1941,8 +1862,10 @@ v8::Local<Value> v8::TryCatch::StackTrace() const {
i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
i::Handle<i::String> name = isolate_->factory()->stack_string();
if (!i::JSReceiver::HasProperty(obj, name)) return v8::Local<Value>();
- i::Handle<i::Object> value = i::GetProperty(isolate_, obj, name);
- if (value.is_null()) return v8::Local<Value>();
+ i::Handle<i::Object> value;
+ if (!i::Object::GetProperty(obj, name).ToHandle(&value)) {
+ return v8::Local<Value>();
+ }
return v8::Utils::ToLocal(scope.CloseAndEscape(value));
} else {
return v8::Local<Value>();
@@ -2028,33 +1951,28 @@ v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
}
-static i::Handle<i::Object> CallV8HeapFunction(const char* name,
- i::Handle<i::Object> recv,
- int argc,
- i::Handle<i::Object> argv[],
- bool* has_pending_exception) {
+MUST_USE_RESULT static i::MaybeHandle<i::Object> CallV8HeapFunction(
+ const char* name,
+ i::Handle<i::Object> recv,
+ int argc,
+ i::Handle<i::Object> argv[]) {
i::Isolate* isolate = i::Isolate::Current();
- i::Handle<i::String> fmt_str =
- isolate->factory()->InternalizeUtf8String(name);
- i::Object* object_fun =
- isolate->js_builtins_object()->GetPropertyNoExceptionThrown(*fmt_str);
- i::Handle<i::JSFunction> fun =
- i::Handle<i::JSFunction>(i::JSFunction::cast(object_fun));
- i::Handle<i::Object> value = i::Execution::Call(
- isolate, fun, recv, argc, argv, has_pending_exception);
- return value;
+ i::Handle<i::Object> object_fun =
+ i::Object::GetProperty(
+ isolate, isolate->js_builtins_object(), name).ToHandleChecked();
+ i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(object_fun);
+ return i::Execution::Call(isolate, fun, recv, argc, argv);
}
-static i::Handle<i::Object> CallV8HeapFunction(const char* name,
- i::Handle<i::Object> data,
- bool* has_pending_exception) {
+MUST_USE_RESULT static i::MaybeHandle<i::Object> CallV8HeapFunction(
+ const char* name,
+ i::Handle<i::Object> data) {
i::Handle<i::Object> argv[] = { data };
return CallV8HeapFunction(name,
i::Isolate::Current()->js_builtins_object(),
ARRAY_SIZE(argv),
- argv,
- has_pending_exception);
+ argv);
}
@@ -2065,9 +1983,9 @@ int Message::GetLineNumber() const {
i::HandleScope scope(isolate);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> result = CallV8HeapFunction("GetLineNumber",
- Utils::OpenHandle(this),
- &has_pending_exception);
+ i::Handle<i::Object> result;
+ has_pending_exception = !CallV8HeapFunction(
+ "GetLineNumber", Utils::OpenHandle(this)).ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, 0);
return static_cast<int>(result->Number());
}
@@ -2099,10 +2017,9 @@ int Message::GetStartColumn() const {
i::HandleScope scope(isolate);
i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
- "GetPositionInLine",
- data_obj,
- &has_pending_exception);
+ i::Handle<i::Object> start_col_obj;
+ has_pending_exception = !CallV8HeapFunction(
+ "GetPositionInLine", data_obj).ToHandle(&start_col_obj);
EXCEPTION_BAILOUT_CHECK(isolate, 0);
return static_cast<int>(start_col_obj->Number());
}
@@ -2114,10 +2031,9 @@ int Message::GetEndColumn() const {
i::HandleScope scope(isolate);
i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
- "GetPositionInLine",
- data_obj,
- &has_pending_exception);
+ i::Handle<i::Object> start_col_obj;
+ has_pending_exception = !CallV8HeapFunction(
+ "GetPositionInLine", data_obj).ToHandle(&start_col_obj);
EXCEPTION_BAILOUT_CHECK(isolate, 0);
i::Handle<i::JSMessageObject> message =
i::Handle<i::JSMessageObject>::cast(data_obj);
@@ -2146,9 +2062,9 @@ Local<String> Message::GetSourceLine() const {
ENTER_V8(isolate);
EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
- Utils::OpenHandle(this),
- &has_pending_exception);
+ i::Handle<i::Object> result;
+ has_pending_exception = !CallV8HeapFunction(
+ "GetSourceLine", Utils::OpenHandle(this)).ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
if (result->IsString()) {
return scope.Escape(Utils::ToLocal(i::Handle<i::String>::cast(result)));
@@ -2173,7 +2089,7 @@ Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
i::Handle<i::JSArray> self = Utils::OpenHandle(this);
i::Handle<i::Object> obj =
- i::Object::GetElementNoExceptionThrown(isolate, self, index);
+ i::Object::GetElement(isolate, self, index).ToHandleChecked();
i::Handle<i::JSObject> jsobj = i::Handle<i::JSObject>::cast(obj);
return scope.Escape(Utils::StackFrameToLocal(jsobj));
}
@@ -2212,7 +2128,8 @@ int StackFrame::GetLineNumber() const {
ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- i::Handle<i::Object> line = GetProperty(self, "lineNumber");
+ i::Handle<i::Object> line = i::Object::GetProperty(
+ isolate, self, "lineNumber").ToHandleChecked();
if (!line->IsSmi()) {
return Message::kNoLineNumberInfo;
}
@@ -2225,7 +2142,8 @@ int StackFrame::GetColumn() const {
ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- i::Handle<i::Object> column = GetProperty(self, "column");
+ i::Handle<i::Object> column = i::Object::GetProperty(
+ isolate, self, "column").ToHandleChecked();
if (!column->IsSmi()) {
return Message::kNoColumnInfo;
}
@@ -2238,7 +2156,8 @@ int StackFrame::GetScriptId() const {
ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- i::Handle<i::Object> scriptId = GetProperty(self, "scriptId");
+ i::Handle<i::Object> scriptId = i::Object::GetProperty(
+ isolate, self, "scriptId").ToHandleChecked();
if (!scriptId->IsSmi()) {
return Message::kNoScriptIdInfo;
}
@@ -2251,7 +2170,8 @@ Local<String> StackFrame::GetScriptName() const {
ENTER_V8(isolate);
EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- i::Handle<i::Object> name = GetProperty(self, "scriptName");
+ i::Handle<i::Object> name = i::Object::GetProperty(
+ isolate, self, "scriptName").ToHandleChecked();
if (!name->IsString()) {
return Local<String>();
}
@@ -2264,7 +2184,8 @@ Local<String> StackFrame::GetScriptNameOrSourceURL() const {
ENTER_V8(isolate);
EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- i::Handle<i::Object> name = GetProperty(self, "scriptNameOrSourceURL");
+ i::Handle<i::Object> name = i::Object::GetProperty(
+ isolate, self, "scriptNameOrSourceURL").ToHandleChecked();
if (!name->IsString()) {
return Local<String>();
}
@@ -2277,7 +2198,8 @@ Local<String> StackFrame::GetFunctionName() const {
ENTER_V8(isolate);
EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- i::Handle<i::Object> name = GetProperty(self, "functionName");
+ i::Handle<i::Object> name = i::Object::GetProperty(
+ isolate, self, "functionName").ToHandleChecked();
if (!name->IsString()) {
return Local<String>();
}
@@ -2290,7 +2212,8 @@ bool StackFrame::IsEval() const {
ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- i::Handle<i::Object> is_eval = GetProperty(self, "isEval");
+ i::Handle<i::Object> is_eval = i::Object::GetProperty(
+ isolate, self, "isEval").ToHandleChecked();
return is_eval->IsTrue();
}
@@ -2300,7 +2223,8 @@ bool StackFrame::IsConstructor() const {
ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- i::Handle<i::Object> is_constructor = GetProperty(self, "isConstructor");
+ i::Handle<i::Object> is_constructor = i::Object::GetProperty(
+ isolate, self, "isConstructor").ToHandleChecked();
return is_constructor->IsTrue();
}
@@ -2308,20 +2232,18 @@ bool StackFrame::IsConstructor() const {
// --- J S O N ---
Local<Value> JSON::Parse(Local<String> json_string) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Handle<i::String> string = Utils::OpenHandle(*json_string);
+ i::Isolate* isolate = string->GetIsolate();
EnsureInitializedForIsolate(isolate, "v8::JSON::Parse");
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- i::Handle<i::String> source = i::Handle<i::String>(
- FlattenGetString(Utils::OpenHandle(*json_string)));
+ i::Handle<i::String> source = i::String::Flatten(string);
EXCEPTION_PREAMBLE(isolate);
+ i::MaybeHandle<i::Object> maybe_result =
+ source->IsSeqOneByteString() ? i::JsonParser<true>::Parse(source)
+ : i::JsonParser<false>::Parse(source);
i::Handle<i::Object> result;
- if (source->IsSeqOneByteString()) {
- result = i::JsonParser<true>::Parse(source);
- } else {
- result = i::JsonParser<false>::Parse(source);
- }
- has_pending_exception = result.is_null();
+ has_pending_exception = !maybe_result.ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
return Utils::ToLocal(
i::Handle<i::Object>::cast(scope.CloseAndEscape(result)));
@@ -2453,60 +2375,55 @@ bool Value::IsUint32() const {
bool Value::IsDate() const {
- i::Isolate* isolate = i::Isolate::Current();
i::Handle<i::Object> obj = Utils::OpenHandle(this);
+ if (!obj->IsHeapObject()) return false;
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
return obj->HasSpecificClassOf(isolate->heap()->Date_string());
}
bool Value::IsStringObject() const {
- i::Isolate* isolate = i::Isolate::Current();
i::Handle<i::Object> obj = Utils::OpenHandle(this);
+ if (!obj->IsHeapObject()) return false;
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
return obj->HasSpecificClassOf(isolate->heap()->String_string());
}
bool Value::IsSymbolObject() const {
- // TODO(svenpanne): these and other test functions should be written such
- // that they do not use Isolate::Current().
- i::Isolate* isolate = i::Isolate::Current();
i::Handle<i::Object> obj = Utils::OpenHandle(this);
+ if (!obj->IsHeapObject()) return false;
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
return obj->HasSpecificClassOf(isolate->heap()->Symbol_string());
}
bool Value::IsNumberObject() const {
- i::Isolate* isolate = i::Isolate::Current();
i::Handle<i::Object> obj = Utils::OpenHandle(this);
+ if (!obj->IsHeapObject()) return false;
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
return obj->HasSpecificClassOf(isolate->heap()->Number_string());
}
-static i::Object* LookupBuiltin(i::Isolate* isolate,
- const char* builtin_name) {
- i::Handle<i::String> string =
- isolate->factory()->InternalizeUtf8String(builtin_name);
- i::Handle<i::JSBuiltinsObject> builtins = isolate->js_builtins_object();
- return builtins->GetPropertyNoExceptionThrown(*string);
-}
-
-
static bool CheckConstructor(i::Isolate* isolate,
i::Handle<i::JSObject> obj,
const char* class_name) {
- i::Object* constr = obj->map()->constructor();
+ i::Handle<i::Object> constr(obj->map()->constructor(), isolate);
if (!constr->IsJSFunction()) return false;
- i::JSFunction* func = i::JSFunction::cast(constr);
- return func->shared()->native() &&
- constr == LookupBuiltin(isolate, class_name);
+ i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(constr);
+ return func->shared()->native() && constr.is_identical_to(
+ i::Object::GetProperty(isolate,
+ isolate->js_builtins_object(),
+ class_name).ToHandleChecked());
}
bool Value::IsNativeError() const {
- i::Isolate* isolate = i::Isolate::Current();
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (obj->IsJSObject()) {
i::Handle<i::JSObject> js_obj(i::JSObject::cast(*obj));
+ i::Isolate* isolate = js_obj->GetIsolate();
return CheckConstructor(isolate, js_obj, "$Error") ||
CheckConstructor(isolate, js_obj, "$EvalError") ||
CheckConstructor(isolate, js_obj, "$RangeError") ||
@@ -2521,8 +2438,9 @@ bool Value::IsNativeError() const {
bool Value::IsBooleanObject() const {
- i::Isolate* isolate = i::Isolate::Current();
i::Handle<i::Object> obj = Utils::OpenHandle(this);
+ if (!obj->IsHeapObject()) return false;
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
return obj->HasSpecificClassOf(isolate->heap()->Boolean_string());
}
@@ -2543,7 +2461,8 @@ Local<String> Value::ToString() const {
LOG_API(isolate, "ToString");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- str = i::Execution::ToString(isolate, obj, &has_pending_exception);
+ has_pending_exception = !i::Execution::ToString(
+ isolate, obj).ToHandle(&str);
EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
}
return ToApiHandle<String>(str);
@@ -2560,7 +2479,8 @@ Local<String> Value::ToDetailString() const {
LOG_API(isolate, "ToDetailString");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- str = i::Execution::ToDetailString(isolate, obj, &has_pending_exception);
+ has_pending_exception = !i::Execution::ToDetailString(
+ isolate, obj).ToHandle(&str);
EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
}
return ToApiHandle<String>(str);
@@ -2577,7 +2497,8 @@ Local<v8::Object> Value::ToObject() const {
LOG_API(isolate, "ToObject");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- val = i::Execution::ToObject(isolate, obj, &has_pending_exception);
+ has_pending_exception = !i::Execution::ToObject(
+ isolate, obj).ToHandle(&val);
EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
}
return ToApiHandle<Object>(val);
@@ -2605,11 +2526,12 @@ Local<Number> Value::ToNumber() const {
if (obj->IsNumber()) {
num = obj;
} else {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
LOG_API(isolate, "ToNumber");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- num = i::Execution::ToNumber(isolate, obj, &has_pending_exception);
+ has_pending_exception = !i::Execution::ToNumber(
+ isolate, obj).ToHandle(&num);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
}
return ToApiHandle<Number>(num);
@@ -2622,11 +2544,12 @@ Local<Integer> Value::ToInteger() const {
if (obj->IsSmi()) {
num = obj;
} else {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
LOG_API(isolate, "ToInteger");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- num = i::Execution::ToInteger(isolate, obj, &has_pending_exception);
+ has_pending_exception = !i::Execution::ToInteger(
+ isolate, obj).ToHandle(&num);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
}
return ToApiHandle<Integer>(num);
@@ -2769,45 +2692,55 @@ void v8::DataView::CheckCast(Value* that) {
void v8::Date::CheckCast(v8::Value* that) {
- i::Isolate* isolate = i::Isolate::Current();
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Date_string()),
+ i::Isolate* isolate = NULL;
+ if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
+ Utils::ApiCheck(isolate != NULL &&
+ obj->HasSpecificClassOf(isolate->heap()->Date_string()),
"v8::Date::Cast()",
"Could not convert to date");
}
void v8::StringObject::CheckCast(v8::Value* that) {
- i::Isolate* isolate = i::Isolate::Current();
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->HasSpecificClassOf(isolate->heap()->String_string()),
+ i::Isolate* isolate = NULL;
+ if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
+ Utils::ApiCheck(isolate != NULL &&
+ obj->HasSpecificClassOf(isolate->heap()->String_string()),
"v8::StringObject::Cast()",
"Could not convert to StringObject");
}
void v8::SymbolObject::CheckCast(v8::Value* that) {
- i::Isolate* isolate = i::Isolate::Current();
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Symbol_string()),
+ i::Isolate* isolate = NULL;
+ if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
+ Utils::ApiCheck(isolate != NULL &&
+ obj->HasSpecificClassOf(isolate->heap()->Symbol_string()),
"v8::SymbolObject::Cast()",
"Could not convert to SymbolObject");
}
void v8::NumberObject::CheckCast(v8::Value* that) {
- i::Isolate* isolate = i::Isolate::Current();
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Number_string()),
+ i::Isolate* isolate = NULL;
+ if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
+ Utils::ApiCheck(isolate != NULL &&
+ obj->HasSpecificClassOf(isolate->heap()->Number_string()),
"v8::NumberObject::Cast()",
"Could not convert to NumberObject");
}
void v8::BooleanObject::CheckCast(v8::Value* that) {
- i::Isolate* isolate = i::Isolate::Current();
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Boolean_string()),
+ i::Isolate* isolate = NULL;
+ if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
+ Utils::ApiCheck(isolate != NULL &&
+ obj->HasSpecificClassOf(isolate->heap()->Boolean_string()),
"v8::BooleanObject::Cast()",
"Could not convert to BooleanObject");
}
@@ -2832,11 +2765,12 @@ double Value::NumberValue() const {
if (obj->IsNumber()) {
num = obj;
} else {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
LOG_API(isolate, "NumberValue");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- num = i::Execution::ToNumber(isolate, obj, &has_pending_exception);
+ has_pending_exception = !i::Execution::ToNumber(
+ isolate, obj).ToHandle(&num);
EXCEPTION_BAILOUT_CHECK(isolate, i::OS::nan_value());
}
return num->Number();
@@ -2849,11 +2783,12 @@ int64_t Value::IntegerValue() const {
if (obj->IsNumber()) {
num = obj;
} else {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
LOG_API(isolate, "IntegerValue");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- num = i::Execution::ToInteger(isolate, obj, &has_pending_exception);
+ has_pending_exception = !i::Execution::ToInteger(
+ isolate, obj).ToHandle(&num);
EXCEPTION_BAILOUT_CHECK(isolate, 0);
}
if (num->IsSmi()) {
@@ -2870,11 +2805,11 @@ Local<Int32> Value::ToInt32() const {
if (obj->IsSmi()) {
num = obj;
} else {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
LOG_API(isolate, "ToInt32");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- num = i::Execution::ToInt32(isolate, obj, &has_pending_exception);
+ has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
}
return ToApiHandle<Int32>(num);
@@ -2887,11 +2822,12 @@ Local<Uint32> Value::ToUint32() const {
if (obj->IsSmi()) {
num = obj;
} else {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
LOG_API(isolate, "ToUInt32");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- num = i::Execution::ToUint32(isolate, obj, &has_pending_exception);
+ has_pending_exception = !i::Execution::ToUint32(
+ isolate, obj).ToHandle(&num);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
}
return ToApiHandle<Uint32>(num);
@@ -2904,12 +2840,13 @@ Local<Uint32> Value::ToArrayIndex() const {
if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
return Local<Uint32>();
}
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
LOG_API(isolate, "ToArrayIndex");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> string_obj =
- i::Execution::ToString(isolate, obj, &has_pending_exception);
+ i::Handle<i::Object> string_obj;
+ has_pending_exception = !i::Execution::ToString(
+ isolate, obj).ToHandle(&string_obj);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
uint32_t index;
@@ -2931,12 +2868,12 @@ int32_t Value::Int32Value() const {
if (obj->IsSmi()) {
return i::Smi::cast(*obj)->value();
} else {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
LOG_API(isolate, "Int32Value (slow)");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> num =
- i::Execution::ToInt32(isolate, obj, &has_pending_exception);
+ i::Handle<i::Object> num;
+ has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num);
EXCEPTION_BAILOUT_CHECK(isolate, 0);
if (num->IsSmi()) {
return i::Smi::cast(*num)->value();
@@ -2966,9 +2903,9 @@ bool Value::Equals(Handle<Value> that) const {
}
i::Handle<i::Object> args[] = { other };
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> result =
- CallV8HeapFunction("EQUALS", obj, ARRAY_SIZE(args), args,
- &has_pending_exception);
+ i::Handle<i::Object> result;
+ has_pending_exception = !CallV8HeapFunction(
+ "EQUALS", obj, ARRAY_SIZE(args), args).ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, false);
return *result == i::Smi::FromInt(i::EQUAL);
}
@@ -2997,7 +2934,8 @@ bool Value::StrictEquals(Handle<Value> that) const {
return other->IsNumber() && obj->Number() == other->Number();
} else if (obj->IsString()) {
return other->IsString() &&
- i::String::cast(*obj)->Equals(i::String::cast(*other));
+ i::String::Equals(i::Handle<i::String>::cast(obj),
+ i::Handle<i::String>::cast(other));
} else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
return other->IsUndefined() || other->IsUndetectableObject();
} else {
@@ -3007,13 +2945,11 @@ bool Value::StrictEquals(Handle<Value> that) const {
bool Value::SameValue(Handle<Value> that) const {
- i::Isolate* isolate = i::Isolate::Current();
if (!Utils::ApiCheck(this != NULL && !that.IsEmpty(),
"v8::Value::SameValue()",
"Reading from empty handle")) {
return false;
}
- LOG_API(isolate, "SameValue");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::Object> other = Utils::OpenHandle(*that);
return obj->SameValue(*other);
@@ -3025,12 +2961,13 @@ uint32_t Value::Uint32Value() const {
if (obj->IsSmi()) {
return i::Smi::cast(*obj)->value();
} else {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
LOG_API(isolate, "Uint32Value");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> num =
- i::Execution::ToUint32(isolate, obj, &has_pending_exception);
+ i::Handle<i::Object> num;
+ has_pending_exception = !i::Execution::ToUint32(
+ isolate, obj).ToHandle(&num);
EXCEPTION_BAILOUT_CHECK(isolate, 0);
if (num->IsSmi()) {
return i::Smi::cast(*num)->value();
@@ -3051,14 +2988,13 @@ bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> obj = i::Runtime::SetObjectProperty(
+ has_pending_exception = i::Runtime::SetObjectProperty(
isolate,
self,
key_obj,
value_obj,
static_cast<PropertyAttributes>(attribs),
- i::SLOPPY);
- has_pending_exception = obj.is_null();
+ i::SLOPPY).is_null();
EXCEPTION_BAILOUT_CHECK(isolate, false);
return true;
}
@@ -3072,13 +3008,8 @@ bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> obj = i::JSObject::SetElement(
- self,
- index,
- value_obj,
- NONE,
- i::SLOPPY);
- has_pending_exception = obj.is_null();
+ has_pending_exception = i::JSObject::SetElement(
+ self, index, value_obj, NONE, i::SLOPPY).is_null();
EXCEPTION_BAILOUT_CHECK(isolate, false);
return true;
}
@@ -3095,12 +3026,11 @@ bool v8::Object::ForceSet(v8::Handle<Value> key,
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> obj = i::ForceSetProperty(
+ has_pending_exception = i::Runtime::ForceSetObjectProperty(
self,
key_obj,
value_obj,
- static_cast<PropertyAttributes>(attribs));
- has_pending_exception = obj.is_null();
+ static_cast<PropertyAttributes>(attribs)).is_null();
EXCEPTION_BAILOUT_CHECK(isolate, false);
return true;
}
@@ -3129,8 +3059,9 @@ bool v8::Object::ForceDelete(v8::Handle<Value> key) {
}
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj);
- has_pending_exception = obj.is_null();
+ i::Handle<i::Object> obj;
+ has_pending_exception = !i::Runtime::DeleteObjectProperty(
+ isolate, self, key_obj, i::JSReceiver::FORCE_DELETION).ToHandle(&obj);
EXCEPTION_BAILOUT_CHECK(isolate, false);
return obj->IsTrue();
}
@@ -3143,8 +3074,9 @@ Local<Value> v8::Object::Get(v8::Handle<Value> key) {
i::Handle<i::Object> self = Utils::OpenHandle(this);
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> result = i::GetProperty(isolate, self, key_obj);
- has_pending_exception = result.is_null();
+ i::Handle<i::Object> result;
+ has_pending_exception =
+ !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
return Utils::ToLocal(result);
}
@@ -3156,8 +3088,9 @@ Local<Value> v8::Object::Get(uint32_t index) {
ENTER_V8(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> result = i::Object::GetElement(isolate, self, index);
- has_pending_exception = result.is_null();
+ i::Handle<i::Object> result;
+ has_pending_exception =
+ !i::Object::GetElement(isolate, self, index).ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
return Utils::ToLocal(result);
}
@@ -3178,7 +3111,8 @@ PropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) {
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
if (!key_obj->IsName()) {
EXCEPTION_PREAMBLE(isolate);
- key_obj = i::Execution::ToString(isolate, key_obj, &has_pending_exception);
+ has_pending_exception = !i::Execution::ToString(
+ isolate, key_obj).ToHandle(&key_obj);
EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
}
i::Handle<i::Name> key_name = i::Handle<i::Name>::cast(key_obj);
@@ -3210,7 +3144,8 @@ bool v8::Object::SetPrototype(Handle<Value> value) {
// to propagate outside.
TryCatch try_catch;
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> result = i::JSObject::SetPrototype(self, value_obj);
+ i::MaybeHandle<i::Object> result = i::JSObject::SetPrototype(
+ self, value_obj);
has_pending_exception = result.is_null();
EXCEPTION_BAILOUT_CHECK(isolate, false);
return true;
@@ -3242,10 +3177,11 @@ Local<Array> v8::Object::GetPropertyNames() {
ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- bool threw = false;
- i::Handle<i::FixedArray> value =
- i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS, &threw);
- if (threw) return Local<v8::Array>();
+ EXCEPTION_PREAMBLE(isolate);
+ i::Handle<i::FixedArray> value;
+ has_pending_exception = !i::JSReceiver::GetKeys(
+ self, i::JSReceiver::INCLUDE_PROTOS).ToHandle(&value);
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Array>());
// Because we use caching to speed up enumeration it is important
// to never change the result of the basic enumeration function so
// we clone the result.
@@ -3263,10 +3199,11 @@ Local<Array> v8::Object::GetOwnPropertyNames() {
ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- bool threw = false;
- i::Handle<i::FixedArray> value =
- i::GetKeysInFixedArrayFor(self, i::LOCAL_ONLY, &threw);
- if (threw) return Local<v8::Array>();
+ EXCEPTION_PREAMBLE(isolate);
+ i::Handle<i::FixedArray> value;
+ has_pending_exception = !i::JSReceiver::GetKeys(
+ self, i::JSReceiver::LOCAL_ONLY).ToHandle(&value);
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Array>());
// Because we use caching to speed up enumeration it is important
// to never change the result of the basic enumeration function so
// we clone the result.
@@ -3361,8 +3298,9 @@ bool v8::Object::Delete(v8::Handle<Value> key) {
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> obj = i::DeleteProperty(self, key_obj);
- has_pending_exception = obj.is_null();
+ i::Handle<i::Object> obj;
+ has_pending_exception = !i::Runtime::DeleteObjectProperty(
+ isolate, self, key_obj, i::JSReceiver::NORMAL_DELETION).ToHandle(&obj);
EXCEPTION_BAILOUT_CHECK(isolate, false);
return obj->IsTrue();
}
@@ -3380,8 +3318,9 @@ bool v8::Object::Has(v8::Handle<Value> key) {
i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> obj = i::HasProperty(self, key_obj);
- has_pending_exception = obj.is_null();
+ i::Handle<i::Object> obj;
+ has_pending_exception = !i::Runtime::HasObjectProperty(
+ isolate, self, key_obj).ToHandle(&obj);
EXCEPTION_BAILOUT_CHECK(isolate, false);
return obj->IsTrue();
}
@@ -3399,7 +3338,13 @@ bool v8::Object::Delete(uint32_t index) {
ENTER_V8(isolate);
HandleScope scope(reinterpret_cast<Isolate*>(isolate));
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- return i::JSReceiver::DeleteElement(self, index)->IsTrue();
+
+ EXCEPTION_PREAMBLE(isolate);
+ i::Handle<i::Object> obj;
+ has_pending_exception =
+ !i::JSReceiver::DeleteElement(self, index).ToHandle(&obj);
+ EXCEPTION_BAILOUT_CHECK(isolate, false);
+ return obj->IsTrue();
}
@@ -3428,9 +3373,12 @@ static inline bool ObjectSetAccessor(Object* obj,
name, getter, setter, data, settings, attributes, signature);
if (info.is_null()) return false;
bool fast = Utils::OpenHandle(obj)->HasFastProperties();
- i::Handle<i::Object> result =
- i::JSObject::SetAccessor(Utils::OpenHandle(obj), info);
- if (result.is_null() || result->IsUndefined()) return false;
+ i::Handle<i::Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, result,
+ i::JSObject::SetAccessor(Utils::OpenHandle(obj), info),
+ false);
+ if (result->IsUndefined()) return false;
if (fast) i::JSObject::TransformToFastProperties(Utils::OpenHandle(obj), 0);
return true;
}
@@ -3544,10 +3492,9 @@ static Local<Value> GetPropertyByLookup(i::Isolate* isolate,
// an exception.
EXCEPTION_PREAMBLE(isolate);
PropertyAttributes ignored;
- i::Handle<i::Object> result =
- i::Object::GetProperty(receiver, receiver, lookup, name,
- &ignored);
- has_pending_exception = result.is_null();
+ i::Handle<i::Object> result;
+ has_pending_exception = !i::Object::GetProperty(
+ receiver, receiver, lookup, name, &ignored).ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
return Utils::ToLocal(result);
@@ -3564,7 +3511,7 @@ Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
i::LookupResult lookup(isolate);
- self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
+ self_obj->LookupRealNamedPropertyInPrototypes(key_obj, &lookup);
return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
}
@@ -3577,7 +3524,7 @@ Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
i::LookupResult lookup(isolate);
- self_obj->LookupRealNamedProperty(*key_obj, &lookup);
+ self_obj->LookupRealNamedProperty(key_obj, &lookup);
return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup);
}
@@ -3596,8 +3543,7 @@ void v8::Object::TurnOnAccessCheck() {
// as optimized code does not always handle access checks.
i::Deoptimizer::DeoptimizeGlobalObject(*obj);
- i::Handle<i::Map> new_map =
- isolate->factory()->CopyMap(i::Handle<i::Map>(obj->map()));
+ i::Handle<i::Map> new_map = i::Map::Copy(i::Handle<i::Map>(obj->map()));
new_map->set_is_access_check_needed(true);
obj->set_map(*new_map);
}
@@ -3614,35 +3560,20 @@ Local<v8::Object> v8::Object::Clone() {
ENTER_V8(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::JSObject> result = i::JSObject::Copy(self);
+ i::Handle<i::JSObject> result = isolate->factory()->CopyJSObject(self);
has_pending_exception = result.is_null();
EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
return Utils::ToLocal(result);
}
-static i::Context* GetCreationContext(i::JSObject* object) {
- i::Object* constructor = object->map()->constructor();
- i::JSFunction* function;
- if (!constructor->IsJSFunction()) {
- // Functions have null as a constructor,
- // but any JSFunction knows its context immediately.
- ASSERT(object->IsJSFunction());
- function = i::JSFunction::cast(object);
- } else {
- function = i::JSFunction::cast(constructor);
- }
- return function->context()->native_context();
-}
-
-
Local<v8::Context> v8::Object::CreationContext() {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate,
"v8::Object::CreationContext()", return Local<v8::Context>());
ENTER_V8(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- i::Context* context = GetCreationContext(*self);
+ i::Context* context = self->GetCreationContext();
return Utils::ToLocal(i::Handle<i::Context>(context));
}
@@ -3685,7 +3616,7 @@ v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
i::Handle<i::String> key_string =
isolate->factory()->InternalizeString(key_obj);
- i::Handle<i::Object> result(self->GetHiddenProperty(*key_string), isolate);
+ i::Handle<i::Object> result(self->GetHiddenProperty(key_string), isolate);
if (result->IsTheHole()) return v8::Local<v8::Value>();
return Utils::ToLocal(result);
}
@@ -3735,8 +3666,7 @@ void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
object,
GetElementsKindFromExternalArrayType(array_type));
- object->set_map(*external_array_map);
- object->set_elements(*array);
+ i::JSObject::SetMapAndElements(object, external_array_map, array);
}
} // namespace
@@ -3901,15 +3831,17 @@ Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Value> recv,
fun = i::Handle<i::JSFunction>::cast(obj);
} else {
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> delegate = i::Execution::TryGetFunctionDelegate(
- isolate, obj, &has_pending_exception);
+ i::Handle<i::Object> delegate;
+ has_pending_exception = !i::Execution::TryGetFunctionDelegate(
+ isolate, obj).ToHandle(&delegate);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
fun = i::Handle<i::JSFunction>::cast(delegate);
recv_obj = obj;
}
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> returned = i::Execution::Call(
- isolate, fun, recv_obj, argc, args, &has_pending_exception, true);
+ i::Handle<i::Object> returned;
+ has_pending_exception = !i::Execution::Call(
+ isolate, fun, recv_obj, argc, args, true).ToHandle(&returned);
EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
return Utils::ToLocal(scope.CloseAndEscape(returned));
}
@@ -3931,21 +3863,24 @@ Local<v8::Value> Object::CallAsConstructor(int argc,
if (obj->IsJSFunction()) {
i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> returned =
- i::Execution::New(fun, argc, args, &has_pending_exception);
+ i::Handle<i::Object> returned;
+ has_pending_exception = !i::Execution::New(
+ fun, argc, args).ToHandle(&returned);
EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
return Utils::ToLocal(scope.CloseAndEscape(
i::Handle<i::JSObject>::cast(returned)));
}
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> delegate = i::Execution::TryGetConstructorDelegate(
- isolate, obj, &has_pending_exception);
+ i::Handle<i::Object> delegate;
+ has_pending_exception = !i::Execution::TryGetConstructorDelegate(
+ isolate, obj).ToHandle(&delegate);
EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
if (!delegate->IsUndefined()) {
i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> returned = i::Execution::Call(
- isolate, fun, obj, argc, args, &has_pending_exception);
+ i::Handle<i::Object> returned;
+ has_pending_exception = !i::Execution::Call(
+ isolate, fun, obj, argc, args).ToHandle(&returned);
EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
ASSERT(!delegate->IsUndefined());
return Utils::ToLocal(scope.CloseAndEscape(returned));
@@ -3986,8 +3921,9 @@ Local<v8::Object> Function::NewInstance(int argc,
STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> returned =
- i::Execution::New(function, argc, args, &has_pending_exception);
+ i::Handle<i::Object> returned;
+ has_pending_exception = !i::Execution::New(
+ function, argc, args).ToHandle(&returned);
EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
return scope.Escape(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
}
@@ -4001,21 +3937,17 @@ Local<v8::Value> Function::Call(v8::Handle<v8::Value> recv, int argc,
ENTER_V8(isolate);
i::Logger::TimerEventScope timer_scope(
isolate, i::Logger::TimerEventScope::v8_execute);
- i::Object* raw_result = NULL;
- {
- i::HandleScope scope(isolate);
- i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
- i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
- STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
- i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> returned = i::Execution::Call(
- isolate, fun, recv_obj, argc, args, &has_pending_exception, true);
- EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Object>());
- raw_result = *returned;
- }
- i::Handle<i::Object> result(raw_result, isolate);
- return Utils::ToLocal(result);
+ i::HandleScope scope(isolate);
+ i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
+ i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
+ STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
+ i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
+ EXCEPTION_PREAMBLE(isolate);
+ i::Handle<i::Object> returned;
+ has_pending_exception = !i::Execution::Call(
+ isolate, fun, recv_obj, argc, args, true).ToHandle(&returned);
+ EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Object>());
+ return Utils::ToLocal(scope.CloseAndEscape(returned));
}
@@ -4053,7 +3985,7 @@ Handle<Value> Function::GetDisplayName() const {
isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("displayName"));
i::LookupResult lookup(isolate);
- func->LookupRealNamedProperty(*property_name, &lookup);
+ func->LookupRealNamedProperty(property_name, &lookup);
if (lookup.IsFound()) {
i::Object* value = lookup.GetLazyValue();
if (value && value->IsString()) {
@@ -4069,7 +4001,7 @@ ScriptOrigin Function::GetScriptOrigin() const {
i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
if (func->shared()->script()->IsScript()) {
i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
- i::Handle<i::Object> scriptName = GetScriptNameOrSourceURL(script);
+ i::Handle<i::Object> scriptName = i::Script::GetNameOrSourceURL(script);
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(func->GetIsolate());
v8::ScriptOrigin origin(
Utils::ToLocal(scriptName),
@@ -4088,7 +4020,7 @@ int Function::GetScriptLineNumber() const {
i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
if (func->shared()->script()->IsScript()) {
i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
- return i::GetScriptLineNumber(script, func->shared()->start_position());
+ return i::Script::GetLineNumber(script, func->shared()->start_position());
}
return kLineOffsetNotFound;
}
@@ -4098,7 +4030,7 @@ int Function::GetScriptColumnNumber() const {
i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
if (func->shared()->script()->IsScript()) {
i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
- return i::GetScriptColumnNumber(script, func->shared()->start_position());
+ return i::Script::GetColumnNumber(script, func->shared()->start_position());
}
return kLineOffsetNotFound;
}
@@ -4678,7 +4610,7 @@ int String::WriteUtf8(char* buffer,
ENTER_V8(isolate);
i::Handle<i::String> str = Utils::OpenHandle(this);
if (options & HINT_MANY_WRITES_EXPECTED) {
- FlattenString(str); // Flatten the string for efficiency.
+ str = i::String::Flatten(str); // Flatten the string for efficiency.
}
const int string_length = str->length();
bool write_null = !(options & NO_NULL_TERMINATION);
@@ -4713,7 +4645,7 @@ int String::WriteUtf8(char* buffer,
}
}
// Recursive slow path can potentially be unreasonable slow. Flatten.
- str = FlattenGetString(str);
+ str = i::String::Flatten(str);
Utf8WriterVisitor writer(buffer, capacity, false, replace_invalid_utf8);
i::String::VisitFlat(&writer, *str);
return writer.CompleteWrite(write_null, nchars_ref);
@@ -4735,7 +4667,7 @@ static inline int WriteHelper(const String* string,
if (options & String::HINT_MANY_WRITES_EXPECTED) {
// Flatten the string for efficiency. This applies whether we are
// using StringCharacterStream or Get(i) to access the characters.
- FlattenString(str);
+ str = i::String::Flatten(str);
}
int end = start + length;
if ((length == -1) || (length > str->length() - start) )
@@ -5288,9 +5220,9 @@ Local<v8::Object> ObjectTemplate::NewInstance() {
LOG_API(isolate, "ObjectTemplate::NewInstance");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> obj =
- i::Execution::InstantiateObject(Utils::OpenHandle(this),
- &has_pending_exception);
+ i::Handle<i::Object> obj;
+ has_pending_exception = !i::Execution::InstantiateObject(
+ Utils::OpenHandle(this)).ToHandle(&obj);
EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
}
@@ -5303,9 +5235,9 @@ Local<v8::Function> FunctionTemplate::GetFunction() {
LOG_API(isolate, "FunctionTemplate::GetFunction");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> obj =
- i::Execution::InstantiateFunction(Utils::OpenHandle(this),
- &has_pending_exception);
+ i::Handle<i::Object> obj;
+ has_pending_exception = !i::Execution::InstantiateFunction(
+ Utils::OpenHandle(this)).ToHandle(&obj);
EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
}
@@ -5356,19 +5288,21 @@ inline int StringLength(const uint16_t* string) {
}
-inline i::Handle<i::String> NewString(i::Factory* factory,
- String::NewStringType type,
- i::Vector<const char> string) {
- if (type ==String::kInternalizedString) {
+MUST_USE_RESULT
+inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
+ String::NewStringType type,
+ i::Vector<const char> string) {
+ if (type == String::kInternalizedString) {
return factory->InternalizeUtf8String(string);
}
return factory->NewStringFromUtf8(string);
}
-inline i::Handle<i::String> NewString(i::Factory* factory,
- String::NewStringType type,
- i::Vector<const uint8_t> string) {
+MUST_USE_RESULT
+inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
+ String::NewStringType type,
+ i::Vector<const uint8_t> string) {
if (type == String::kInternalizedString) {
return factory->InternalizeOneByteString(string);
}
@@ -5376,9 +5310,10 @@ inline i::Handle<i::String> NewString(i::Factory* factory,
}
-inline i::Handle<i::String> NewString(i::Factory* factory,
- String::NewStringType type,
- i::Vector<const uint16_t> string) {
+MUST_USE_RESULT
+inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
+ String::NewStringType type,
+ i::Vector<const uint16_t> string) {
if (type == String::kInternalizedString) {
return factory->InternalizeTwoByteString(string);
}
@@ -5401,10 +5336,11 @@ inline Local<String> NewString(Isolate* v8_isolate,
}
ENTER_V8(isolate);
if (length == -1) length = StringLength(data);
- i::Handle<i::String> result = NewString(
- isolate->factory(), type, i::Vector<const Char>(data, length));
// We do not expect this to fail. Change this if it does.
- CHECK(!result.is_null());
+ i::Handle<i::String> result = NewString(
+ isolate->factory(),
+ type,
+ i::Vector<const Char>(data, length)).ToHandleChecked();
if (type == String::kUndetectableString) {
result->MarkAsUndetectable();
}
@@ -5460,10 +5396,9 @@ Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
LOG_API(isolate, "String::New(char)");
ENTER_V8(isolate);
i::Handle<i::String> right_string = Utils::OpenHandle(*right);
- i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
- right_string);
// We do not expect this to fail. Change this if it does.
- CHECK(!result.is_null());
+ i::Handle<i::String> result = isolate->factory()->NewConsString(
+ left_string, right_string).ToHandleChecked();
return Utils::ToLocal(result);
}
@@ -5471,22 +5406,18 @@ Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
static i::Handle<i::String> NewExternalStringHandle(
i::Isolate* isolate,
v8::String::ExternalStringResource* resource) {
- i::Handle<i::String> result =
- isolate->factory()->NewExternalStringFromTwoByte(resource);
// We do not expect this to fail. Change this if it does.
- CHECK(!result.is_null());
- return result;
+ return isolate->factory()->NewExternalStringFromTwoByte(
+ resource).ToHandleChecked();
}
static i::Handle<i::String> NewExternalAsciiStringHandle(
i::Isolate* isolate,
v8::String::ExternalAsciiStringResource* resource) {
- i::Handle<i::String> result =
- isolate->factory()->NewExternalStringFromAscii(resource);
// We do not expect this to fail. Change this if it does.
- CHECK(!result.is_null());
- return result;
+ return isolate->factory()->NewExternalStringFromAscii(
+ resource).ToHandleChecked();
}
@@ -5603,16 +5534,17 @@ Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
LOG_API(i_isolate, "NumberObject::New");
ENTER_V8(i_isolate);
i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
- i::Handle<i::Object> obj = i_isolate->factory()->ToObject(number);
+ i::Handle<i::Object> obj =
+ i::Object::ToObject(i_isolate, number).ToHandleChecked();
return Utils::ToLocal(obj);
}
double v8::NumberObject::ValueOf() const {
- i::Isolate* isolate = i::Isolate::Current();
- LOG_API(isolate, "NumberObject::NumberValue");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
+ i::Isolate* isolate = jsvalue->GetIsolate();
+ LOG_API(isolate, "NumberObject::NumberValue");
return jsvalue->value()->Number();
}
@@ -5626,36 +5558,38 @@ Local<v8::Value> v8::BooleanObject::New(bool value) {
? isolate->heap()->true_value()
: isolate->heap()->false_value(),
isolate);
- i::Handle<i::Object> obj = isolate->factory()->ToObject(boolean);
+ i::Handle<i::Object> obj =
+ i::Object::ToObject(isolate, boolean).ToHandleChecked();
return Utils::ToLocal(obj);
}
bool v8::BooleanObject::ValueOf() const {
- i::Isolate* isolate = i::Isolate::Current();
- LOG_API(isolate, "BooleanObject::BooleanValue");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
+ i::Isolate* isolate = jsvalue->GetIsolate();
+ LOG_API(isolate, "BooleanObject::BooleanValue");
return jsvalue->value()->IsTrue();
}
Local<v8::Value> v8::StringObject::New(Handle<String> value) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Handle<i::String> string = Utils::OpenHandle(*value);
+ i::Isolate* isolate = string->GetIsolate();
EnsureInitializedForIsolate(isolate, "v8::StringObject::New()");
LOG_API(isolate, "StringObject::New");
ENTER_V8(isolate);
i::Handle<i::Object> obj =
- isolate->factory()->ToObject(Utils::OpenHandle(*value));
+ i::Object::ToObject(isolate, string).ToHandleChecked();
return Utils::ToLocal(obj);
}
Local<v8::String> v8::StringObject::ValueOf() const {
- i::Isolate* isolate = i::Isolate::Current();
- LOG_API(isolate, "StringObject::StringValue");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
+ i::Isolate* isolate = jsvalue->GetIsolate();
+ LOG_API(isolate, "StringObject::StringValue");
return Utils::ToLocal(
i::Handle<i::String>(i::String::cast(jsvalue->value())));
}
@@ -5666,17 +5600,17 @@ Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Handle<Symbol> value) {
EnsureInitializedForIsolate(i_isolate, "v8::SymbolObject::New()");
LOG_API(i_isolate, "SymbolObject::New");
ENTER_V8(i_isolate);
- i::Handle<i::Object> obj =
- i_isolate->factory()->ToObject(Utils::OpenHandle(*value));
+ i::Handle<i::Object> obj = i::Object::ToObject(
+ i_isolate, Utils::OpenHandle(*value)).ToHandleChecked();
return Utils::ToLocal(obj);
}
Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
- i::Isolate* isolate = i::Isolate::Current();
- LOG_API(isolate, "SymbolObject::SymbolValue");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
+ i::Isolate* isolate = jsvalue->GetIsolate();
+ LOG_API(isolate, "SymbolObject::SymbolValue");
return Utils::ToLocal(
i::Handle<i::Symbol>(i::Symbol::cast(jsvalue->value())));
}
@@ -5692,24 +5626,26 @@ Local<v8::Value> v8::Date::New(Isolate* isolate, double time) {
}
ENTER_V8(i_isolate);
EXCEPTION_PREAMBLE(i_isolate);
- i::Handle<i::Object> obj =
- i::Execution::NewDate(i_isolate, time, &has_pending_exception);
+ i::Handle<i::Object> obj;
+ has_pending_exception = !i::Execution::NewDate(
+ i_isolate, time).ToHandle(&obj);
EXCEPTION_BAILOUT_CHECK(i_isolate, Local<v8::Value>());
return Utils::ToLocal(obj);
}
double v8::Date::ValueOf() const {
- i::Isolate* isolate = i::Isolate::Current();
- LOG_API(isolate, "Date::NumberValue");
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
+ i::Isolate* isolate = jsdate->GetIsolate();
+ LOG_API(isolate, "Date::NumberValue");
return jsdate->value()->Number();
}
void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ if (!i_isolate->IsInitialized()) return;
ON_BAILOUT(i_isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
return);
LOG_API(i_isolate, "Date::DateTimeConfigurationChangeNotification");
@@ -5752,10 +5688,10 @@ Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
LOG_API(isolate, "RegExp::New");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
+ i::Handle<i::JSRegExp> obj;
+ has_pending_exception = !i::Execution::NewJSRegExp(
Utils::OpenHandle(*pattern),
- RegExpFlagsToString(flags),
- &has_pending_exception);
+ RegExpFlagsToString(flags)).ToHandle(&obj);
EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
}
@@ -5823,7 +5759,8 @@ Local<Object> Array::CloneElementAt(uint32_t index) {
i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
EXCEPTION_PREAMBLE(isolate);
ENTER_V8(isolate);
- i::Handle<i::JSObject> result = i::JSObject::Copy(paragon_handle);
+ i::Handle<i::JSObject> result =
+ isolate->factory()->CopyJSObject(paragon_handle);
has_pending_exception = result.is_null();
EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
return Utils::ToLocal(result);
@@ -5839,14 +5776,14 @@ bool Value::IsPromise() const {
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> argv[] = { obj };
- i::Handle<i::Object> b = i::Execution::Call(
+ i::Handle<i::Object> b;
+ has_pending_exception = !i::Execution::Call(
isolate,
handle(
isolate->context()->global_object()->native_context()->is_promise()),
isolate->factory()->undefined_value(),
ARRAY_SIZE(argv), argv,
- &has_pending_exception,
- false);
+ false).ToHandle(&b);
EXCEPTION_BAILOUT_CHECK(isolate, false);
return b->BooleanValue();
}
@@ -5857,14 +5794,14 @@ Local<Promise::Resolver> Promise::Resolver::New(Isolate* v8_isolate) {
LOG_API(isolate, "Promise::Resolver::New");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> result = i::Execution::Call(
+ i::Handle<i::Object> result;
+ has_pending_exception = !i::Execution::Call(
isolate,
handle(isolate->context()->global_object()->native_context()->
promise_create()),
isolate->factory()->undefined_value(),
0, NULL,
- &has_pending_exception,
- false);
+ false).ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise::Resolver>());
return Local<Promise::Resolver>::Cast(Utils::ToLocal(result));
}
@@ -5883,14 +5820,13 @@ void Promise::Resolver::Resolve(Handle<Value> value) {
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> argv[] = { promise, Utils::OpenHandle(*value) };
- i::Execution::Call(
+ has_pending_exception = i::Execution::Call(
isolate,
handle(isolate->context()->global_object()->native_context()->
promise_resolve()),
isolate->factory()->undefined_value(),
ARRAY_SIZE(argv), argv,
- &has_pending_exception,
- false);
+ false).is_null();
EXCEPTION_BAILOUT_CHECK(isolate, /* void */ ;);
}
@@ -5902,14 +5838,13 @@ void Promise::Resolver::Reject(Handle<Value> value) {
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> argv[] = { promise, Utils::OpenHandle(*value) };
- i::Execution::Call(
+ has_pending_exception = i::Execution::Call(
isolate,
handle(isolate->context()->global_object()->native_context()->
promise_reject()),
isolate->factory()->undefined_value(),
ARRAY_SIZE(argv), argv,
- &has_pending_exception,
- false);
+ false).is_null();
EXCEPTION_BAILOUT_CHECK(isolate, /* void */ ;);
}
@@ -5921,14 +5856,14 @@ Local<Promise> Promise::Chain(Handle<Function> handler) {
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
- i::Handle<i::Object> result = i::Execution::Call(
+ i::Handle<i::Object> result;
+ has_pending_exception = !i::Execution::Call(
isolate,
handle(isolate->context()->global_object()->native_context()->
promise_chain()),
promise,
ARRAY_SIZE(argv), argv,
- &has_pending_exception,
- false);
+ false).ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
return Local<Promise>::Cast(Utils::ToLocal(result));
}
@@ -5941,14 +5876,14 @@ Local<Promise> Promise::Catch(Handle<Function> handler) {
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
- i::Handle<i::Object> result = i::Execution::Call(
+ i::Handle<i::Object> result;
+ has_pending_exception = !i::Execution::Call(
isolate,
handle(isolate->context()->global_object()->native_context()->
promise_catch()),
promise,
ARRAY_SIZE(argv), argv,
- &has_pending_exception,
- false);
+ false).ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
return Local<Promise>::Cast(Utils::ToLocal(result));
}
@@ -6085,6 +6020,7 @@ i::Handle<i::JSTypedArray> NewTypedArray(
ASSERT(byte_offset % sizeof(ElementType) == 0);
CHECK(length <= (std::numeric_limits<size_t>::max() / sizeof(ElementType)));
+ CHECK(length <= static_cast<size_t>(i::Smi::kMaxValue));
size_t byte_length = length * sizeof(ElementType);
SetupArrayBufferView(
isolate, obj, buffer, byte_offset, byte_length);
@@ -6099,7 +6035,7 @@ i::Handle<i::JSTypedArray> NewTypedArray(
static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
i::Handle<i::Map> map =
i::JSObject::GetElementsTransitionMap(obj, elements_kind);
- obj->set_map_and_elements(*map, *elements);
+ i::JSObject::SetMapAndElements(obj, map, elements);
return obj;
}
@@ -6107,12 +6043,17 @@ i::Handle<i::JSTypedArray> NewTypedArray(
#define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \
Local<Type##Array> Type##Array::New(Handle<ArrayBuffer> array_buffer, \
size_t byte_offset, size_t length) { \
- i::Isolate* isolate = i::Isolate::Current(); \
+ i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \
EnsureInitializedForIsolate(isolate, \
"v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)"); \
LOG_API(isolate, \
"v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)"); \
ENTER_V8(isolate); \
+ if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue), \
+ "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)", \
+ "length exceeds max allowed value")) { \
+ return Local<Type##Array>(); \
+ } \
i::Handle<i::JSTypedArray> obj = \
NewTypedArray<ctype, v8::kExternal##Type##Array, \
i::EXTERNAL_##TYPE##_ELEMENTS>( \
@@ -6126,13 +6067,13 @@ TYPED_ARRAYS(TYPED_ARRAY_NEW)
Local<DataView> DataView::New(Handle<ArrayBuffer> array_buffer,
size_t byte_offset, size_t byte_length) {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
+ i::Isolate* isolate = buffer->GetIsolate();
EnsureInitializedForIsolate(
isolate, "v8::DataView::New(void*, size_t, size_t)");
LOG_API(isolate, "v8::DataView::New(void*, size_t, size_t)");
ENTER_V8(isolate);
i::Handle<i::JSDataView> obj = isolate->factory()->NewJSDataView();
- i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
SetupArrayBufferView(
isolate, obj, buffer, byte_offset, byte_length);
return Utils::ToLocal(obj);
@@ -6156,13 +6097,16 @@ Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) {
i::Handle<i::JSObject> registry = i_isolate->GetSymbolRegistry();
i::Handle<i::String> part = i_isolate->factory()->for_string();
i::Handle<i::JSObject> symbols =
- i::Handle<i::JSObject>::cast(i::JSObject::GetProperty(registry, part));
- i::Handle<i::Object> symbol = i::JSObject::GetProperty(symbols, i_name);
+ i::Handle<i::JSObject>::cast(
+ i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
+ i::Handle<i::Object> symbol =
+ i::Object::GetPropertyOrElement(symbols, i_name).ToHandleChecked();
if (!symbol->IsSymbol()) {
ASSERT(symbol->IsUndefined());
symbol = i_isolate->factory()->NewSymbol();
i::Handle<i::Symbol>::cast(symbol)->set_name(*i_name);
- i::JSObject::SetProperty(symbols, i_name, symbol, NONE, i::STRICT);
+ i::JSObject::SetProperty(
+ symbols, i_name, symbol, NONE, i::STRICT).Assert();
}
return Utils::ToLocal(i::Handle<i::Symbol>::cast(symbol));
}
@@ -6174,13 +6118,16 @@ Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) {
i::Handle<i::JSObject> registry = i_isolate->GetSymbolRegistry();
i::Handle<i::String> part = i_isolate->factory()->for_api_string();
i::Handle<i::JSObject> symbols =
- i::Handle<i::JSObject>::cast(i::JSObject::GetProperty(registry, part));
- i::Handle<i::Object> symbol = i::JSObject::GetProperty(symbols, i_name);
+ i::Handle<i::JSObject>::cast(
+ i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
+ i::Handle<i::Object> symbol =
+ i::Object::GetPropertyOrElement(symbols, i_name).ToHandleChecked();
if (!symbol->IsSymbol()) {
ASSERT(symbol->IsUndefined());
symbol = i_isolate->factory()->NewSymbol();
i::Handle<i::Symbol>::cast(symbol)->set_name(*i_name);
- i::JSObject::SetProperty(symbols, i_name, symbol, NONE, i::STRICT);
+ i::JSObject::SetProperty(
+ symbols, i_name, symbol, NONE, i::STRICT).Assert();
}
return Utils::ToLocal(i::Handle<i::Symbol>::cast(symbol));
}
@@ -6204,13 +6151,16 @@ Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) {
i::Handle<i::JSObject> registry = i_isolate->GetSymbolRegistry();
i::Handle<i::String> part = i_isolate->factory()->private_api_string();
i::Handle<i::JSObject> privates =
- i::Handle<i::JSObject>::cast(i::JSObject::GetProperty(registry, part));
- i::Handle<i::Object> symbol = i::JSObject::GetProperty(privates, i_name);
+ i::Handle<i::JSObject>::cast(
+ i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
+ i::Handle<i::Object> symbol =
+ i::Object::GetPropertyOrElement(privates, i_name).ToHandleChecked();
if (!symbol->IsSymbol()) {
ASSERT(symbol->IsUndefined());
symbol = i_isolate->factory()->NewPrivateSymbol();
i::Handle<i::Symbol>::cast(symbol)->set_name(*i_name);
- i::JSObject::SetProperty(privates, i_name, symbol, NONE, i::STRICT);
+ i::JSObject::SetProperty(
+ privates, i_name, symbol, NONE, i::STRICT).Assert();
}
Local<Symbol> result = Utils::ToLocal(i::Handle<i::Symbol>::cast(symbol));
return v8::Handle<Private>(reinterpret_cast<Private*>(*result));
@@ -6303,13 +6253,17 @@ void V8::SetCaptureStackTraceForUncaughtExceptions(
void V8::SetCounterFunction(CounterLookupCallback callback) {
- i::Isolate* isolate = EnterIsolateIfNeeded();
+ i::Isolate* isolate = i::Isolate::UncheckedCurrent();
+ // TODO(svenpanne) The Isolate should really be a parameter.
+ if (isolate == NULL) return;
isolate->stats_table()->SetCounterFunction(callback);
}
void V8::SetCreateHistogramFunction(CreateHistogramCallback callback) {
- i::Isolate* isolate = EnterIsolateIfNeeded();
+ i::Isolate* isolate = i::Isolate::UncheckedCurrent();
+ // TODO(svenpanne) The Isolate should really be a parameter.
+ if (isolate == NULL) return;
isolate->stats_table()->SetCreateHistogramFunction(callback);
isolate->InitializeLoggingAndCounters();
isolate->counters()->ResetHistograms();
@@ -6317,7 +6271,9 @@ void V8::SetCreateHistogramFunction(CreateHistogramCallback callback) {
void V8::SetAddHistogramSampleFunction(AddHistogramSampleCallback callback) {
- i::Isolate* isolate = EnterIsolateIfNeeded();
+ i::Isolate* isolate = i::Isolate::UncheckedCurrent();
+ // TODO(svenpanne) The Isolate should really be a parameter.
+ if (isolate == NULL) return;
isolate->stats_table()->
SetAddHistogramSampleFunction(callback);
}
@@ -6498,43 +6454,23 @@ void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
}
-void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
- if (callback == NULL) return;
- i::V8::AddCallCompletedCallback(callback);
-}
-
-
void V8::RunMicrotasks(Isolate* isolate) {
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- i::HandleScope scope(i_isolate);
- i::V8::RunMicrotasks(i_isolate);
+ isolate->RunMicrotasks();
}
void V8::EnqueueMicrotask(Isolate* isolate, Handle<Function> microtask) {
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- ENTER_V8(i_isolate);
- i::Execution::EnqueueMicrotask(i_isolate, Utils::OpenHandle(*microtask));
+ isolate->EnqueueMicrotask(microtask);
}
void V8::SetAutorunMicrotasks(Isolate* isolate, bool autorun) {
- reinterpret_cast<i::Isolate*>(isolate)->set_autorun_microtasks(autorun);
-}
-
-
-void V8::RemoveCallCompletedCallback(CallCompletedCallback callback) {
- i::V8::RemoveCallCompletedCallback(callback);
+ isolate->SetAutorunMicrotasks(autorun);
}
void V8::TerminateExecution(Isolate* isolate) {
- // If no isolate is supplied, use the default isolate.
- if (isolate != NULL) {
- reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->TerminateExecution();
- } else {
- i::Isolate::GetDefaultIsolateStackGuard()->TerminateExecution();
- }
+ reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->TerminateExecution();
}
@@ -6653,6 +6589,18 @@ Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
}
+Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
+ Isolate* isolate)
+ : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
+ isolate_->handle_scope_implementer()->IncrementCallDepth();
+}
+
+
+Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
+ isolate_->handle_scope_implementer()->DecrementCallDepth();
+}
+
+
void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
if (!isolate->IsInitialized()) {
@@ -6678,6 +6626,39 @@ void Isolate::SetEventLogger(LogEventCallback that) {
isolate->set_event_logger(that);
}
+
+void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
+ if (callback == NULL) return;
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->AddCallCompletedCallback(callback);
+}
+
+
+void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->RemoveCallCompletedCallback(callback);
+}
+
+
+void Isolate::RunMicrotasks() {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
+ i::HandleScope scope(i_isolate);
+ i_isolate->RunMicrotasks();
+}
+
+
+void Isolate::EnqueueMicrotask(Handle<Function> microtask) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
+ ENTER_V8(i_isolate);
+ i::Execution::EnqueueMicrotask(i_isolate, Utils::OpenHandle(*microtask));
+}
+
+
+void Isolate::SetAutorunMicrotasks(bool autorun) {
+ reinterpret_cast<i::Isolate*>(this)->set_autorun_microtasks(autorun);
+}
+
+
String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
: str_(NULL), length_(0) {
i::Isolate* isolate = i::Isolate::Current();
@@ -6807,8 +6788,6 @@ Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
// --- D e b u g S u p p o r t ---
-#ifdef ENABLE_DEBUGGER_SUPPORT
-
bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
@@ -6837,34 +6816,19 @@ bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
void Debug::DebugBreak(Isolate* isolate) {
- // If no isolate is supplied, use the default isolate.
- if (isolate != NULL) {
- reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->DebugBreak();
- } else {
- i::Isolate::GetDefaultIsolateStackGuard()->DebugBreak();
- }
+ reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->DebugBreak();
}
void Debug::CancelDebugBreak(Isolate* isolate) {
- // If no isolate is supplied, use the default isolate.
- if (isolate != NULL) {
- i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
- internal_isolate->stack_guard()->Continue(i::DEBUGBREAK);
- } else {
- i::Isolate::GetDefaultIsolateStackGuard()->Continue(i::DEBUGBREAK);
- }
+ i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ internal_isolate->stack_guard()->Continue(i::DEBUGBREAK);
}
-void Debug::DebugBreakForCommand(ClientData* data, Isolate* isolate) {
- // If no isolate is supplied, use the default isolate.
- if (isolate != NULL) {
- i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
- internal_isolate->debugger()->EnqueueDebugCommand(data);
- } else {
- i::Isolate::GetDefaultIsolateDebugger()->EnqueueDebugCommand(data);
- }
+void Debug::DebugBreakForCommand(Isolate* isolate, ClientData* data) {
+ i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ internal_isolate->debugger()->EnqueueDebugCommand(data);
}
@@ -6886,21 +6850,6 @@ void Debug::SendCommand(Isolate* isolate,
}
-void Debug::SendCommand(const uint16_t* command, int length,
- ClientData* client_data,
- Isolate* isolate) {
- // If no isolate is supplied, use the default isolate.
- if (isolate != NULL) {
- i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
- internal_isolate->debugger()->ProcessCommand(
- i::Vector<const uint16_t>(command, length), client_data);
- } else {
- i::Isolate::GetDefaultIsolateDebugger()->ProcessCommand(
- i::Vector<const uint16_t>(command, length), client_data);
- }
-}
-
-
void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
int period) {
i::Isolate* isolate = i::Isolate::Current();
@@ -6928,17 +6877,17 @@ Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
if (!isolate->IsInitialized()) return Local<Value>();
ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
ENTER_V8(isolate);
- i::Handle<i::Object> result;
+ i::MaybeHandle<i::Object> maybe_result;
EXCEPTION_PREAMBLE(isolate);
if (data.IsEmpty()) {
- result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
- isolate->factory()->undefined_value(),
- &has_pending_exception);
+ maybe_result = isolate->debugger()->Call(
+ Utils::OpenHandle(*fun), isolate->factory()->undefined_value());
} else {
- result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
- Utils::OpenHandle(*data),
- &has_pending_exception);
+ maybe_result = isolate->debugger()->Call(
+ Utils::OpenHandle(*fun), Utils::OpenHandle(*data));
}
+ i::Handle<i::Object> result;
+ has_pending_exception = !maybe_result.ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
return Utils::ToLocal(result);
}
@@ -6951,18 +6900,23 @@ Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
ENTER_V8(isolate);
v8::EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
i::Debug* isolate_debug = isolate->debug();
- isolate_debug->Load();
- i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global_object());
- i::Handle<i::String> name = isolate->factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("MakeMirror"));
- i::Handle<i::Object> fun_obj = i::GetProperty(isolate, debug, name);
- i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
- v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
- const int kArgc = 1;
- v8::Handle<v8::Value> argv[kArgc] = { obj };
EXCEPTION_PREAMBLE(isolate);
- v8::Local<v8::Value> result =
- v8_fun->Call(Utils::ToLocal(debug), kArgc, argv);
+ has_pending_exception = !isolate_debug->Load();
+ v8::Local<v8::Value> result;
+ if (!has_pending_exception) {
+ i::Handle<i::JSObject> debug(
+ isolate_debug->debug_context()->global_object());
+ i::Handle<i::String> name = isolate->factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("MakeMirror"));
+ i::Handle<i::Object> fun_obj =
+ i::Object::GetProperty(debug, name).ToHandleChecked();
+ i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
+ v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
+ const int kArgc = 1;
+ v8::Handle<v8::Value> argv[kArgc] = { obj };
+ result = v8_fun->Call(Utils::ToLocal(debug), kArgc, argv);
+ has_pending_exception = result.IsEmpty();
+ }
EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
return scope.Escape(result);
}
@@ -6992,35 +6946,25 @@ Local<Context> Debug::GetDebugContext() {
}
-void Debug::SetLiveEditEnabled(bool enable, Isolate* isolate) {
- // If no isolate is supplied, use the default isolate.
- i::Debugger* debugger;
- if (isolate != NULL) {
- i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
- debugger = internal_isolate->debugger();
- } else {
- debugger = i::Isolate::GetDefaultIsolateDebugger();
- }
- debugger->set_live_edit_enabled(enable);
+void Debug::SetLiveEditEnabled(Isolate* isolate, bool enable) {
+ i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ internal_isolate->debugger()->set_live_edit_enabled(enable);
}
-#endif // ENABLE_DEBUGGER_SUPPORT
-
-
Handle<String> CpuProfileNode::GetFunctionName() const {
i::Isolate* isolate = i::Isolate::Current();
const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
const i::CodeEntry* entry = node->entry();
+ i::Handle<i::String> name =
+ isolate->factory()->InternalizeUtf8String(entry->name());
if (!entry->has_name_prefix()) {
- return ToApiHandle<String>(
- isolate->factory()->InternalizeUtf8String(entry->name()));
+ return ToApiHandle<String>(name);
} else {
+ // We do not expect this to fail. Change this if it does.
i::Handle<i::String> cons = isolate->factory()->NewConsString(
isolate->factory()->InternalizeUtf8String(entry->name_prefix()),
- isolate->factory()->InternalizeUtf8String(entry->name()));
- // We do not expect this to fail. Change this if it does.
- CHECK(!cons.is_null());
+ name).ToHandleChecked();
return ToApiHandle<String>(cons);
}
}
@@ -7113,15 +7057,21 @@ const CpuProfileNode* CpuProfile::GetSample(int index) const {
}
+int64_t CpuProfile::GetSampleTimestamp(int index) const {
+ const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
+ return (profile->sample_timestamp(index) - i::TimeTicks()).InMicroseconds();
+}
+
+
int64_t CpuProfile::GetStartTime() const {
const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
- return (profile->start_time() - i::Time::UnixEpoch()).InMicroseconds();
+ return (profile->start_time() - i::TimeTicks()).InMicroseconds();
}
int64_t CpuProfile::GetEndTime() const {
const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
- return (profile->end_time() - i::Time::UnixEpoch()).InMicroseconds();
+ return (profile->end_time() - i::TimeTicks()).InMicroseconds();
}
diff --git a/deps/v8/src/api.h b/deps/v8/src/api.h
index 128087c895..f530e56f94 100644
--- a/deps/v8/src/api.h
+++ b/deps/v8/src/api.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_API_H_
#define V8_API_H_
@@ -186,9 +163,9 @@ class RegisteredExtension {
V(Script, JSFunction) \
V(UnboundScript, SharedFunctionInfo) \
V(Function, JSFunction) \
- V(Message, JSObject) \
+ V(Message, JSMessageObject) \
V(Context, Context) \
- V(External, Foreign) \
+ V(External, Object) \
V(StackTrace, JSArray) \
V(StackFrame, JSObject) \
V(DeclaredAccessorDescriptor, DeclaredAccessorDescriptor)
@@ -393,8 +370,8 @@ MAKE_TO_LOCAL(ToLocal, DeclaredAccessorDescriptor, DeclaredAccessorDescriptor)
const v8::From* that, bool allow_empty_handle) { \
EXTRA_CHECK(allow_empty_handle || that != NULL); \
EXTRA_CHECK(that == NULL || \
- !(*reinterpret_cast<v8::internal::To**>( \
- const_cast<v8::From*>(that)))->IsFailure()); \
+ (*reinterpret_cast<v8::internal::Object**>( \
+ const_cast<v8::From*>(that)))->Is##To()); \
return v8::internal::Handle<v8::internal::To>( \
reinterpret_cast<v8::internal::To**>(const_cast<v8::From*>(that))); \
}
diff --git a/deps/v8/src/apinatives.js b/deps/v8/src/apinatives.js
index 6431901bf2..0579caf544 100644
--- a/deps/v8/src/apinatives.js
+++ b/deps/v8/src/apinatives.js
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file contains infrastructure used by the API. See
// v8natives.js for an explanation of these files are processed and
@@ -71,31 +48,29 @@ function InstantiateFunction(data, name) {
(serialNumber in cache) && (cache[serialNumber] != kUninitialized);
if (!isFunctionCached) {
try {
- var fun = %CreateApiFunction(data);
- if (name) %FunctionSetName(fun, name);
var flags = %GetTemplateField(data, kApiFlagOffset);
- var doNotCache = flags & (1 << kDoNotCacheBit);
- if (!doNotCache) cache[serialNumber] = fun;
- if (flags & (1 << kRemovePrototypeBit)) {
- %FunctionRemovePrototype(fun);
- } else {
- var prototype = %GetTemplateField(data, kApiPrototypeTemplateOffset);
- // Note: Do not directly use an object template as a condition, our
- // internal ToBoolean doesn't handle that!
- fun.prototype = typeof prototype === 'undefined' ?
- {} : Instantiate(prototype);
- if (flags & (1 << kReadOnlyPrototypeBit)) {
- %FunctionSetReadOnlyPrototype(fun);
- }
- %SetProperty(fun.prototype, "constructor", fun, DONT_ENUM);
+ var has_proto = !(flags & (1 << kRemovePrototypeBit));
+ var prototype;
+ if (has_proto) {
+ var template = %GetTemplateField(data, kApiPrototypeTemplateOffset);
+ prototype = typeof template === 'undefined'
+ ? {} : Instantiate(template);
+
var parent = %GetTemplateField(data, kApiParentTemplateOffset);
// Note: Do not directly use a function template as a condition, our
// internal ToBoolean doesn't handle that!
- if (!(typeof parent === 'undefined')) {
+ if (typeof parent !== 'undefined') {
var parent_fun = Instantiate(parent);
- %SetPrototype(fun.prototype, parent_fun.prototype);
+ %SetPrototype(prototype, parent_fun.prototype);
}
}
+ var fun = %CreateApiFunction(data, prototype);
+ if (name) %FunctionSetName(fun, name);
+ var doNotCache = flags & (1 << kDoNotCacheBit);
+ if (!doNotCache) cache[serialNumber] = fun;
+ if (has_proto && flags & (1 << kReadOnlyPrototypeBit)) {
+ %FunctionSetReadOnlyPrototype(fun);
+ }
ConfigureTemplateInstance(fun, data);
if (doNotCache) return fun;
} catch (e) {
diff --git a/deps/v8/src/arguments.cc b/deps/v8/src/arguments.cc
index 205da7c68a..72420eea8f 100644
--- a/deps/v8/src/arguments.cc
+++ b/deps/v8/src/arguments.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
#include "arguments.h"
diff --git a/deps/v8/src/arguments.h b/deps/v8/src/arguments.h
index b7137c3175..eb75724f2b 100644
--- a/deps/v8/src/arguments.h
+++ b/deps/v8/src/arguments.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARGUMENTS_H_
#define V8_ARGUMENTS_H_
@@ -299,10 +276,10 @@ double ClobberDoubleRegisters(double x1, double x2, double x3, double x4);
#endif
-#define DECLARE_RUNTIME_FUNCTION(Type, Name) \
-Type Name(int args_length, Object** args_object, Isolate* isolate)
+#define DECLARE_RUNTIME_FUNCTION(Name) \
+Object* Name(int args_length, Object** args_object, Isolate* isolate)
-#define RUNTIME_FUNCTION(Type, Name) \
+#define RUNTIME_FUNCTION_RETURNS_TYPE(Type, Name) \
static Type __RT_impl_##Name(Arguments args, Isolate* isolate); \
Type Name(int args_length, Object** args_object, Isolate* isolate) { \
CLOBBER_DOUBLE_REGISTERS(); \
@@ -311,6 +288,11 @@ Type Name(int args_length, Object** args_object, Isolate* isolate) { \
} \
static Type __RT_impl_##Name(Arguments args, Isolate* isolate)
+
+#define RUNTIME_FUNCTION(Name) RUNTIME_FUNCTION_RETURNS_TYPE(Object*, Name)
+#define RUNTIME_FUNCTION_RETURN_PAIR(Name) \
+ RUNTIME_FUNCTION_RETURNS_TYPE(ObjectPair, Name)
+
#define RUNTIME_ARGUMENTS(isolate, args) \
args.length(), args.arguments(), isolate
diff --git a/deps/v8/src/arm/assembler-arm-inl.h b/deps/v8/src/arm/assembler-arm-inl.h
index d966380c1e..f5612e463c 100644
--- a/deps/v8/src/arm/assembler-arm-inl.h
+++ b/deps/v8/src/arm/assembler-arm-inl.h
@@ -222,7 +222,7 @@ void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode mode) {
}
-static const int kNoCodeAgeSequenceLength = 3;
+static const int kNoCodeAgeSequenceLength = 3 * Assembler::kInstrSize;
Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) {
@@ -234,15 +234,15 @@ Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) {
Code* RelocInfo::code_age_stub() {
ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
return Code::GetCodeFromTargetAddress(
- Memory::Address_at(pc_ + Assembler::kInstrSize *
- (kNoCodeAgeSequenceLength - 1)));
+ Memory::Address_at(pc_ +
+ (kNoCodeAgeSequenceLength - Assembler::kInstrSize)));
}
void RelocInfo::set_code_age_stub(Code* stub) {
ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
- Memory::Address_at(pc_ + Assembler::kInstrSize *
- (kNoCodeAgeSequenceLength - 1)) =
+ Memory::Address_at(pc_ +
+ (kNoCodeAgeSequenceLength - Assembler::kInstrSize)) =
stub->instruction_start();
}
@@ -323,14 +323,12 @@ void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
visitor->VisitExternalReference(this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
visitor->VisitCodeAgeSequence(this);
-#ifdef ENABLE_DEBUGGER_SUPPORT
} else if (((RelocInfo::IsJSReturn(mode) &&
IsPatchedReturnSequence()) ||
(RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence())) &&
isolate->debug()->has_break_points()) {
visitor->VisitDebugTarget(this);
-#endif
} else if (RelocInfo::IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this);
}
@@ -350,14 +348,12 @@ void RelocInfo::Visit(Heap* heap) {
StaticVisitor::VisitExternalReference(this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
StaticVisitor::VisitCodeAgeSequence(heap, this);
-#ifdef ENABLE_DEBUGGER_SUPPORT
} else if (heap->isolate()->debug()->has_break_points() &&
((RelocInfo::IsJSReturn(mode) &&
IsPatchedReturnSequence()) ||
(RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence()))) {
StaticVisitor::VisitDebugTarget(heap, this);
-#endif
} else if (RelocInfo::IsRuntimeEntry(mode)) {
StaticVisitor::VisitRuntimeEntry(this);
}
diff --git a/deps/v8/src/arm/assembler-arm.cc b/deps/v8/src/arm/assembler-arm.cc
index 297cdcc039..74fd61979b 100644
--- a/deps/v8/src/arm/assembler-arm.cc
+++ b/deps/v8/src/arm/assembler-arm.cc
@@ -100,10 +100,11 @@ const char* DwVfpRegister::AllocationIndexToString(int index) {
}
-void CpuFeatures::Probe() {
+void CpuFeatures::Probe(bool serializer_enabled) {
uint64_t standard_features = static_cast<unsigned>(
OS::CpuFeaturesImpliedByPlatform()) | CpuFeaturesImpliedByCompiler();
- ASSERT(supported_ == 0 || supported_ == standard_features);
+ ASSERT(supported_ == 0 ||
+ (supported_ & standard_features) == standard_features);
#ifdef DEBUG
initialized_ = true;
#endif
@@ -113,10 +114,8 @@ void CpuFeatures::Probe() {
// snapshot.
supported_ |= standard_features;
- if (Serializer::enabled()) {
+ if (serializer_enabled) {
// No probing for features if we might serialize (generate snapshot).
- printf(" ");
- PrintFeatures();
return;
}
@@ -1077,15 +1076,11 @@ static bool fits_shifter(uint32_t imm32,
// if they can be encoded in the ARM's 12 bits of immediate-offset instruction
// space. There is no guarantee that the relocated location can be similarly
// encoded.
-bool Operand::must_output_reloc_info(const Assembler* assembler) const {
+bool Operand::must_output_reloc_info(Isolate* isolate,
+ const Assembler* assembler) const {
if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) {
-#ifdef DEBUG
- if (!Serializer::enabled()) {
- Serializer::TooLateToEnableNow();
- }
-#endif // def DEBUG
if (assembler != NULL && assembler->predictable_code_size()) return true;
- return Serializer::enabled();
+ return Serializer::enabled(isolate);
} else if (RelocInfo::IsNone(rmode_)) {
return false;
}
@@ -1093,7 +1088,8 @@ bool Operand::must_output_reloc_info(const Assembler* assembler) const {
}
-static bool use_mov_immediate_load(const Operand& x,
+static bool use_mov_immediate_load(Isolate* isolate,
+ const Operand& x,
const Assembler* assembler) {
if (assembler != NULL && !assembler->can_use_constant_pool()) {
// If there is no constant pool available, we must use an mov immediate.
@@ -1104,7 +1100,7 @@ static bool use_mov_immediate_load(const Operand& x,
(assembler == NULL || !assembler->predictable_code_size())) {
// Prefer movw / movt to constant pool if it is more efficient on the CPU.
return true;
- } else if (x.must_output_reloc_info(assembler)) {
+ } else if (x.must_output_reloc_info(isolate, assembler)) {
// Prefer constant pool if data is likely to be patched.
return false;
} else {
@@ -1114,17 +1110,18 @@ static bool use_mov_immediate_load(const Operand& x,
}
-bool Operand::is_single_instruction(const Assembler* assembler,
+bool Operand::is_single_instruction(Isolate* isolate,
+ const Assembler* assembler,
Instr instr) const {
if (rm_.is_valid()) return true;
uint32_t dummy1, dummy2;
- if (must_output_reloc_info(assembler) ||
+ if (must_output_reloc_info(isolate, assembler) ||
!fits_shifter(imm32_, &dummy1, &dummy2, &instr)) {
// The immediate operand cannot be encoded as a shifter operand, or use of
// constant pool is required. For a mov instruction not setting the
// condition code additional instruction conventions can be used.
if ((instr & ~kCondMask) == 13*B21) { // mov, S not set
- return !use_mov_immediate_load(*this, assembler);
+ return !use_mov_immediate_load(isolate, *this, assembler);
} else {
// If this is not a mov or mvn instruction there will always an additional
// instructions - either mov or ldr. The mov might actually be two
@@ -1144,15 +1141,16 @@ void Assembler::move_32_bit_immediate(Register rd,
const Operand& x,
Condition cond) {
RelocInfo rinfo(pc_, x.rmode_, x.imm32_, NULL);
- if (x.must_output_reloc_info(this)) {
+ if (x.must_output_reloc_info(isolate(), this)) {
RecordRelocInfo(rinfo);
}
- if (use_mov_immediate_load(x, this)) {
+ if (use_mov_immediate_load(isolate(), x, this)) {
Register target = rd.code() == pc.code() ? ip : rd;
// TODO(rmcilroy): add ARMv6 support for immediate loads.
ASSERT(CpuFeatures::IsSupported(ARMv7));
- if (!FLAG_enable_ool_constant_pool && x.must_output_reloc_info(this)) {
+ if (!FLAG_enable_ool_constant_pool &&
+ x.must_output_reloc_info(isolate(), this)) {
// Make sure the movw/movt doesn't get separated.
BlockConstPoolFor(2);
}
@@ -1180,7 +1178,7 @@ void Assembler::addrmod1(Instr instr,
// Immediate.
uint32_t rotate_imm;
uint32_t immed_8;
- if (x.must_output_reloc_info(this) ||
+ if (x.must_output_reloc_info(isolate(), this) ||
!fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) {
// The immediate operand cannot be encoded as a shifter operand, so load
// it first to register ip and change the original instruction to use ip.
@@ -1862,7 +1860,7 @@ void Assembler::msr(SRegisterFieldMask fields, const Operand& src,
// Immediate.
uint32_t rotate_imm;
uint32_t immed_8;
- if (src.must_output_reloc_info(this) ||
+ if (src.must_output_reloc_info(isolate(), this) ||
!fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) {
// Immediate operand cannot be encoded, load it first to register ip.
move_32_bit_immediate(ip, src);
@@ -2827,8 +2825,9 @@ void Assembler::vcvt_f64_s32(const DwVfpRegister dst,
ASSERT(CpuFeatures::IsSupported(VFP3));
int vd, d;
dst.split_code(&vd, &d);
- int i = ((32 - fraction_bits) >> 4) & 1;
- int imm4 = (32 - fraction_bits) & 0xf;
+ int imm5 = 32 - fraction_bits;
+ int i = imm5 & 1;
+ int imm4 = (imm5 >> 1) & 0xf;
emit(cond | 0xE*B24 | B23 | d*B22 | 0x3*B20 | B19 | 0x2*B16 |
vd*B12 | 0x5*B9 | B8 | B7 | B6 | i*B5 | imm4);
}
@@ -3161,9 +3160,7 @@ void Assembler::RecordComment(const char* msg) {
void Assembler::RecordConstPool(int size) {
// We only need this for debugger support, to correctly compute offsets in the
// code.
-#ifdef ENABLE_DEBUGGER_SUPPORT
RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size));
-#endif
}
@@ -3266,12 +3263,7 @@ void Assembler::RecordRelocInfo(const RelocInfo& rinfo) {
if (!RelocInfo::IsNone(rinfo.rmode())) {
// Don't record external references unless the heap will be serialized.
if (rinfo.rmode() == RelocInfo::EXTERNAL_REFERENCE) {
-#ifdef DEBUG
- if (!Serializer::enabled()) {
- Serializer::TooLateToEnableNow();
- }
-#endif
- if (!Serializer::enabled() && !emit_debug_code()) {
+ if (!Serializer::enabled(isolate()) && !emit_debug_code()) {
return;
}
}
@@ -3502,7 +3494,8 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
// data
bool found = false;
- if (!Serializer::enabled() && (rinfo.rmode() >= RelocInfo::CELL)) {
+ if (!Serializer::enabled(isolate()) &&
+ (rinfo.rmode() >= RelocInfo::CELL)) {
for (int j = 0; j < i; j++) {
RelocInfo& rinfo2 = pending_32_bit_reloc_info_[j];
@@ -3547,14 +3540,15 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
}
-MaybeObject* Assembler::AllocateConstantPool(Heap* heap) {
- ASSERT(FLAG_enable_ool_constant_pool);
- return constant_pool_builder_.Allocate(heap);
+Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
+ if (!FLAG_enable_ool_constant_pool) {
+ return isolate->factory()->empty_constant_pool_array();
+ }
+ return constant_pool_builder_.New(isolate);
}
void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
- ASSERT(FLAG_enable_ool_constant_pool);
constant_pool_builder_.Populate(this, constant_pool);
}
@@ -3605,7 +3599,7 @@ void ConstantPoolBuilder::AddEntry(Assembler* assm,
// Try to merge entries which won't be patched.
int merged_index = -1;
if (RelocInfo::IsNone(rmode) ||
- (!Serializer::enabled() && (rmode >= RelocInfo::CELL))) {
+ (!Serializer::enabled(assm->isolate()) && (rmode >= RelocInfo::CELL))) {
size_t i;
std::vector<RelocInfo>::const_iterator it;
for (it = entries_.begin(), i = 0; it != entries_.end(); it++, i++) {
@@ -3654,12 +3648,14 @@ void ConstantPoolBuilder::Relocate(int pc_delta) {
}
-MaybeObject* ConstantPoolBuilder::Allocate(Heap* heap) {
+Handle<ConstantPoolArray> ConstantPoolBuilder::New(Isolate* isolate) {
if (IsEmpty()) {
- return heap->empty_constant_pool_array();
+ return isolate->factory()->empty_constant_pool_array();
} else {
- return heap->AllocateConstantPoolArray(count_of_64bit_, count_of_code_ptr_,
- count_of_heap_ptr_, count_of_32bit_);
+ return isolate->factory()->NewConstantPoolArray(count_of_64bit_,
+ count_of_code_ptr_,
+ count_of_heap_ptr_,
+ count_of_32bit_);
}
}
diff --git a/deps/v8/src/arm/assembler-arm.h b/deps/v8/src/arm/assembler-arm.h
index 727b054211..1c6a7f04f8 100644
--- a/deps/v8/src/arm/assembler-arm.h
+++ b/deps/v8/src/arm/assembler-arm.h
@@ -56,7 +56,7 @@ class CpuFeatures : public AllStatic {
public:
// Detect features of the target CPU. Set safe defaults if the serializer
// is enabled (snapshots must be portable).
- static void Probe();
+ static void Probe(bool serializer_enabled);
// Display target use when compiling.
static void PrintTarget();
@@ -70,15 +70,11 @@ class CpuFeatures : public AllStatic {
return Check(f, supported_);
}
- static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
- ASSERT(initialized_);
- return Check(f, found_by_runtime_probing_only_);
- }
-
- static bool IsSafeForSnapshot(CpuFeature f) {
+ static bool IsSafeForSnapshot(Isolate* isolate, CpuFeature f) {
return Check(f, cross_compile_) ||
(IsSupported(f) &&
- (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
+ !(Serializer::enabled(isolate) &&
+ Check(f, found_by_runtime_probing_only_)));
}
static unsigned cache_line_size() { return cache_line_size_; }
@@ -93,6 +89,8 @@ class CpuFeatures : public AllStatic {
(cross_compile_ & mask) == mask;
}
+ static bool SupportsCrankshaft() { return CpuFeatures::IsSupported(VFP3); }
+
private:
static bool Check(CpuFeature f, unsigned set) {
return (set & flag2set(f)) != 0;
@@ -590,8 +588,11 @@ class Operand BASE_EMBEDDED {
// the instruction this operand is used for is a MOV or MVN instruction the
// actual instruction to use is required for this calculation. For other
// instructions instr is ignored.
- bool is_single_instruction(const Assembler* assembler, Instr instr = 0) const;
- bool must_output_reloc_info(const Assembler* assembler) const;
+ bool is_single_instruction(Isolate* isolate,
+ const Assembler* assembler,
+ Instr instr = 0) const;
+ bool must_output_reloc_info(Isolate* isolate,
+ const Assembler* assembler) const;
inline int32_t immediate() const {
ASSERT(!rm_.is_valid());
@@ -714,7 +715,7 @@ class ConstantPoolBuilder BASE_EMBEDDED {
void AddEntry(Assembler* assm, const RelocInfo& rinfo);
void Relocate(int pc_delta);
bool IsEmpty();
- MaybeObject* Allocate(Heap* heap);
+ Handle<ConstantPoolArray> New(Isolate* isolate);
void Populate(Assembler* assm, ConstantPoolArray* constant_pool);
inline int count_of_64bit() const { return count_of_64bit_; }
@@ -728,6 +729,8 @@ class ConstantPoolBuilder BASE_EMBEDDED {
bool IsCodePtrEntry(RelocInfo::Mode rmode);
bool IsHeapPtrEntry(RelocInfo::Mode rmode);
+ // TODO(rmcilroy): This should ideally be a ZoneList, however that would mean
+ // RelocInfo would need to subclass ZoneObject which it currently doesn't.
std::vector<RelocInfo> entries_;
std::vector<int> merged_indexes_;
int count_of_64bit_;
@@ -1498,7 +1501,7 @@ class Assembler : public AssemblerBase {
void CheckConstPool(bool force_emit, bool require_jump);
// Allocate a constant pool of the correct size for the generated code.
- MaybeObject* AllocateConstantPool(Heap* heap);
+ Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate);
// Generate the constant pool for the generated code.
void PopulateConstantPool(ConstantPoolArray* constant_pool);
diff --git a/deps/v8/src/arm/builtins-arm.cc b/deps/v8/src/arm/builtins-arm.cc
index f138146417..2e5cc7398c 100644
--- a/deps/v8/src/arm/builtins-arm.cc
+++ b/deps/v8/src/arm/builtins-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -376,14 +353,12 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
Label rt_call, allocated;
if (FLAG_inline_new) {
Label undo_allocation;
-#ifdef ENABLE_DEBUGGER_SUPPORT
ExternalReference debug_step_in_fp =
ExternalReference::debug_step_in_fp_address(isolate);
__ mov(r2, Operand(debug_step_in_fp));
__ ldr(r2, MemOperand(r2));
__ tst(r2, r2);
__ b(ne, &rt_call);
-#endif
// Load the initial map and verify that it is in fact a map.
// r1: constructor function
@@ -807,7 +782,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
if (is_construct) {
// No type feedback cell is available
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
- CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
+ CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
ParameterCount actual(r0);
@@ -923,7 +898,7 @@ void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
__ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
// Jump to point after the code-age stub.
- __ add(r0, r0, Operand(kNoCodeAgeSequenceLength * Assembler::kInstrSize));
+ __ add(r0, r0, Operand(kNoCodeAgeSequenceLength));
__ mov(pc, r0);
}
@@ -1284,7 +1259,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// Out of stack space.
__ ldr(r1, MemOperand(fp, kFunctionOffset));
__ Push(r1, r0);
- __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
+ __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
// End of stack check.
// Push current limit and index.
@@ -1407,6 +1382,26 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
}
+static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
+ Label* stack_overflow) {
+ // ----------- S t a t e -------------
+ // -- r0 : actual number of arguments
+ // -- r1 : function (passed through to callee)
+ // -- r2 : expected number of arguments
+ // -----------------------------------
+ // Check the stack for overflow. We are not trying to catch
+ // interruptions (e.g. debug break and preemption) here, so the "real stack
+ // limit" is checked.
+ __ LoadRoot(r5, Heap::kRealStackLimitRootIndex);
+ // Make r5 the space we have left. The stack might already be overflowed
+ // here which will cause r5 to become negative.
+ __ sub(r5, sp, r5);
+ // Check if the arguments will overflow the stack.
+ __ cmp(r5, Operand(r2, LSL, kPointerSizeLog2));
+ __ b(le, stack_overflow); // Signed comparison.
+}
+
+
static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
__ SmiTag(r0);
__ mov(r4, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
@@ -1446,6 +1441,8 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// -- r2 : expected number of arguments
// -----------------------------------
+ Label stack_overflow;
+ ArgumentAdaptorStackCheck(masm, &stack_overflow);
Label invoke, dont_adapt_arguments;
Label enough, too_few;
@@ -1545,6 +1542,14 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// -------------------------------------------
__ bind(&dont_adapt_arguments);
__ Jump(r3);
+
+ __ bind(&stack_overflow);
+ {
+ FrameScope frame(masm, StackFrame::MANUAL);
+ EnterArgumentsAdaptorFrame(masm);
+ __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
+ __ bkpt(0);
+ }
}
diff --git a/deps/v8/src/arm/code-stubs-arm.cc b/deps/v8/src/arm/code-stubs-arm.cc
index 832296b273..7b2935106f 100644
--- a/deps/v8/src/arm/code-stubs-arm.cc
+++ b/deps/v8/src/arm/code-stubs-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -39,7 +16,6 @@ namespace internal {
void FastNewClosureStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r2 };
descriptor->register_param_count_ = 1;
@@ -50,7 +26,6 @@ void FastNewClosureStub::InitializeInterfaceDescriptor(
void FastNewContextStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1 };
descriptor->register_param_count_ = 1;
@@ -60,7 +35,6 @@ void FastNewContextStub::InitializeInterfaceDescriptor(
void ToNumberStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0 };
descriptor->register_param_count_ = 1;
@@ -70,7 +44,6 @@ void ToNumberStub::InitializeInterfaceDescriptor(
void NumberToStringStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0 };
descriptor->register_param_count_ = 1;
@@ -81,7 +54,6 @@ void NumberToStringStub::InitializeInterfaceDescriptor(
void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r3, r2, r1 };
descriptor->register_param_count_ = 3;
@@ -93,7 +65,6 @@ void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r3, r2, r1, r0 };
descriptor->register_param_count_ = 4;
@@ -104,7 +75,6 @@ void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r2, r3 };
descriptor->register_param_count_ = 2;
@@ -114,7 +84,6 @@ void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1, r0 };
descriptor->register_param_count_ = 2;
@@ -125,7 +94,6 @@ void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1, r0 };
descriptor->register_param_count_ = 2;
@@ -136,7 +104,6 @@ void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
void RegExpConstructResultStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r2, r1, r0 };
descriptor->register_param_count_ = 3;
@@ -147,7 +114,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor(
void LoadFieldStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0 };
descriptor->register_param_count_ = 1;
@@ -157,7 +123,6 @@ void LoadFieldStub::InitializeInterfaceDescriptor(
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1 };
descriptor->register_param_count_ = 1;
@@ -167,7 +132,6 @@ void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
void StringLengthStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0, r2 };
descriptor->register_param_count_ = 2;
@@ -177,7 +141,6 @@ void StringLengthStub::InitializeInterfaceDescriptor(
void KeyedStringLengthStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1, r0 };
descriptor->register_param_count_ = 2;
@@ -187,7 +150,6 @@ void KeyedStringLengthStub::InitializeInterfaceDescriptor(
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r2, r1, r0 };
descriptor->register_param_count_ = 3;
@@ -198,7 +160,6 @@ void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
void TransitionElementsKindStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0, r1 };
descriptor->register_param_count_ = 2;
@@ -210,7 +171,6 @@ void TransitionElementsKindStub::InitializeInterfaceDescriptor(
void CompareNilICStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0 };
descriptor->register_param_count_ = 1;
@@ -218,12 +178,11 @@ void CompareNilICStub::InitializeInterfaceDescriptor(
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(CompareNilIC_Miss);
descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate));
+ ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate()));
}
static void InitializeArrayConstructorDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor,
int constant_stack_parameter_count) {
// register state
@@ -252,7 +211,6 @@ static void InitializeArrayConstructorDescriptor(
static void InitializeInternalArrayConstructorDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor,
int constant_stack_parameter_count) {
// register state
@@ -280,28 +238,24 @@ static void InitializeInternalArrayConstructorDescriptor(
void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(isolate, descriptor, 0);
+ InitializeArrayConstructorDescriptor(descriptor, 0);
}
void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(isolate, descriptor, 1);
+ InitializeArrayConstructorDescriptor(descriptor, 1);
}
void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(isolate, descriptor, -1);
+ InitializeArrayConstructorDescriptor(descriptor, -1);
}
void ToBooleanStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0 };
descriptor->register_param_count_ = 1;
@@ -309,33 +263,29 @@ void ToBooleanStub::InitializeInterfaceDescriptor(
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(ToBooleanIC_Miss);
descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate));
+ ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate()));
}
void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 0);
+ InitializeInternalArrayConstructorDescriptor(descriptor, 0);
}
void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 1);
+ InitializeInternalArrayConstructorDescriptor(descriptor, 1);
}
void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(isolate, descriptor, -1);
+ InitializeInternalArrayConstructorDescriptor(descriptor, -1);
}
void StoreGlobalStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1, r2, r0 };
descriptor->register_param_count_ = 3;
@@ -346,7 +296,6 @@ void StoreGlobalStub::InitializeInterfaceDescriptor(
void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r0, r3, r1, r2 };
descriptor->register_param_count_ = 4;
@@ -357,19 +306,17 @@ void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
void BinaryOpICStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1, r0 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate));
+ ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate()));
}
void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r2, r1, r0 };
descriptor->register_param_count_ = 3;
@@ -380,7 +327,6 @@ void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
void StringAddStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { r1, r0 };
descriptor->register_param_count_ = 2;
@@ -504,10 +450,9 @@ static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm,
void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
// Update the static counter each time a new code stub is generated.
- Isolate* isolate = masm->isolate();
- isolate->counters()->code_stubs()->Increment();
+ isolate()->counters()->code_stubs()->Increment();
- CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate);
+ CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor();
int param_count = descriptor->register_param_count_;
{
// Call the runtime system in a fresh internal frame.
@@ -533,11 +478,13 @@ void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
// stub so you don't have to set up the frame.
class ConvertToDoubleStub : public PlatformCodeStub {
public:
- ConvertToDoubleStub(Register result_reg_1,
+ ConvertToDoubleStub(Isolate* isolate,
+ Register result_reg_1,
Register result_reg_2,
Register source_reg,
Register scratch_reg)
- : result1_(result_reg_1),
+ : PlatformCodeStub(isolate),
+ result1_(result_reg_1),
result2_(result_reg_2),
source_(source_reg),
zeros_(scratch_reg) { }
@@ -726,10 +673,10 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
void WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(
Isolate* isolate) {
- WriteInt32ToHeapNumberStub stub1(r1, r0, r2);
- WriteInt32ToHeapNumberStub stub2(r2, r0, r3);
- stub1.GetCode(isolate);
- stub2.GetCode(isolate);
+ WriteInt32ToHeapNumberStub stub1(isolate, r1, r0, r2);
+ WriteInt32ToHeapNumberStub stub2(isolate, r2, r0, r3);
+ stub1.GetCode();
+ stub2.GetCode();
}
@@ -1124,7 +1071,6 @@ void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
__ bind(&both_loaded_as_doubles);
// The arguments have been converted to doubles and stored in d6 and d7, if
// VFP3 is supported, or in r0, r1, r2, and r3.
- Isolate* isolate = masm->isolate();
__ bind(&lhs_not_nan);
Label no_nan;
// ARMv7 VFP3 instructions to implement double precision comparison.
@@ -1187,7 +1133,8 @@ void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
__ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, r2, r3, &slow);
- __ IncrementCounter(isolate->counters()->string_compare_native(), 1, r2, r3);
+ __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, r2,
+ r3);
if (cc == eq) {
StringCompareStub::GenerateFlatAsciiStringEquals(masm,
lhs,
@@ -1251,9 +1198,9 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
AllowExternalCallThatCantCauseGC scope(masm);
__ PrepareCallCFunction(argument_count, fp_argument_count, scratch);
- __ mov(r0, Operand(ExternalReference::isolate_address(masm->isolate())));
+ __ mov(r0, Operand(ExternalReference::isolate_address(isolate())));
__ CallCFunction(
- ExternalReference::store_buffer_overflow_function(masm->isolate()),
+ ExternalReference::store_buffer_overflow_function(isolate()),
argument_count);
if (save_doubles_ == kSaveFPRegs) {
__ RestoreFPRegs(sp, scratch);
@@ -1373,7 +1320,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ PrepareCallCFunction(0, 2, scratch);
__ MovToFloatParameters(double_base, double_exponent);
__ CallCFunction(
- ExternalReference::power_double_double_function(masm->isolate()),
+ ExternalReference::power_double_double_function(isolate()),
0, 2);
}
__ pop(lr);
@@ -1424,11 +1371,11 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ vcvt_f64_s32(double_exponent, single_scratch);
// Returning or bailing out.
- Counters* counters = masm->isolate()->counters();
+ Counters* counters = isolate()->counters();
if (exponent_type_ == ON_STACK) {
// The arguments are still on the stack.
__ bind(&call_runtime);
- __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
+ __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1);
// The stub is called from non-optimized code, which expects the result
// as heap number in exponent.
@@ -1447,7 +1394,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ PrepareCallCFunction(0, 2, scratch);
__ MovToFloatParameters(double_base, double_exponent);
__ CallCFunction(
- ExternalReference::power_double_double_function(masm->isolate()),
+ ExternalReference::power_double_double_function(isolate()),
0, 2);
}
__ pop(lr);
@@ -1479,61 +1426,57 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
void CodeStub::GenerateFPStubs(Isolate* isolate) {
SaveFPRegsMode mode = kSaveFPRegs;
- CEntryStub save_doubles(1, mode);
- StoreBufferOverflowStub stub(mode);
+ CEntryStub save_doubles(isolate, 1, mode);
+ StoreBufferOverflowStub stub(isolate, mode);
// These stubs might already be in the snapshot, detect that and don't
// regenerate, which would lead to code stub initialization state being messed
// up.
Code* save_doubles_code;
- if (!save_doubles.FindCodeInCache(&save_doubles_code, isolate)) {
- save_doubles_code = *save_doubles.GetCode(isolate);
+ if (!save_doubles.FindCodeInCache(&save_doubles_code)) {
+ save_doubles_code = *save_doubles.GetCode();
}
Code* store_buffer_overflow_code;
- if (!stub.FindCodeInCache(&store_buffer_overflow_code, isolate)) {
- store_buffer_overflow_code = *stub.GetCode(isolate);
+ if (!stub.FindCodeInCache(&store_buffer_overflow_code)) {
+ store_buffer_overflow_code = *stub.GetCode();
}
isolate->set_fp_stubs_generated(true);
}
void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
- CEntryStub stub(1, kDontSaveFPRegs);
- stub.GetCode(isolate);
+ CEntryStub stub(isolate, 1, kDontSaveFPRegs);
+ stub.GetCode();
}
-void CEntryStub::GenerateCore(MacroAssembler* masm,
- Label* throw_normal_exception,
- Label* throw_termination_exception,
- bool do_gc,
- bool always_allocate) {
- // r0: result parameter for PerformGC, if any
- // r4: number of arguments including receiver (C callee-saved)
- // r5: pointer to builtin function (C callee-saved)
- // r6: pointer to the first argument (C callee-saved)
- Isolate* isolate = masm->isolate();
-
- if (do_gc) {
- // Passing r0.
- __ PrepareCallCFunction(2, 0, r1);
- __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate())));
- __ CallCFunction(ExternalReference::perform_gc_function(isolate),
- 2, 0);
- }
+void CEntryStub::Generate(MacroAssembler* masm) {
+ // Called from JavaScript; parameters are on stack as if calling JS function.
+ // r0: number of arguments including receiver
+ // r1: pointer to builtin function
+ // fp: frame pointer (restored after C call)
+ // sp: stack pointer (restored as callee's sp after C call)
+ // cp: current context (C callee-saved)
- ExternalReference scope_depth =
- ExternalReference::heap_always_allocate_scope_depth(isolate);
- if (always_allocate) {
- __ mov(r0, Operand(scope_depth));
- __ ldr(r1, MemOperand(r0));
- __ add(r1, r1, Operand(1));
- __ str(r1, MemOperand(r0));
- }
+ ProfileEntryHookStub::MaybeCallEntryHook(masm);
- // Call C built-in.
- // r0 = argc, r1 = argv
- __ mov(r0, Operand(r4));
- __ mov(r1, Operand(r6));
+ __ mov(r5, Operand(r1));
+
+ // Compute the argv pointer in a callee-saved register.
+ __ add(r1, sp, Operand(r0, LSL, kPointerSizeLog2));
+ __ sub(r1, r1, Operand(kPointerSize));
+
+ // Enter the exit frame that transitions from JavaScript to C++.
+ FrameScope scope(masm, StackFrame::MANUAL);
+ __ EnterExitFrame(save_doubles_);
+
+ // Store a copy of argc in callee-saved registers for later.
+ __ mov(r4, Operand(r0));
+
+ // r0, r4: number of arguments including receiver (C callee-saved)
+ // r1: pointer to the first argument (C callee-saved)
+ // r5: pointer to builtin function (C callee-saved)
+
+ // Result returned in r0 or r0+r1 by default.
#if V8_HOST_ARCH_ARM
int frame_alignment = MacroAssembler::ActivationFrameAlignment();
@@ -1551,7 +1494,9 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
}
#endif
- __ mov(r2, Operand(ExternalReference::isolate_address(isolate)));
+ // Call C built-in.
+ // r0 = argc, r1 = argv
+ __ mov(r2, Operand(ExternalReference::isolate_address(isolate())));
// To let the GC traverse the return address of the exit frames, we need to
// know where the return address is. The CEntryStub is unmovable, so
@@ -1570,132 +1515,67 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
__ VFPEnsureFPSCRState(r2);
- if (always_allocate) {
- // It's okay to clobber r2 and r3 here. Don't mess with r0 and r1
- // though (contain the result).
- __ mov(r2, Operand(scope_depth));
- __ ldr(r3, MemOperand(r2));
- __ sub(r3, r3, Operand(1));
- __ str(r3, MemOperand(r2));
+ // Runtime functions should not return 'the hole'. Allowing it to escape may
+ // lead to crashes in the IC code later.
+ if (FLAG_debug_code) {
+ Label okay;
+ __ CompareRoot(r0, Heap::kTheHoleValueRootIndex);
+ __ b(ne, &okay);
+ __ stop("The hole escaped");
+ __ bind(&okay);
}
- // check for failure result
- Label failure_returned;
- STATIC_ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0);
- // Lower 2 bits of r2 are 0 iff r0 has failure tag.
- __ add(r2, r0, Operand(1));
- __ tst(r2, Operand(kFailureTagMask));
- __ b(eq, &failure_returned);
+ // Check result for exception sentinel.
+ Label exception_returned;
+ __ CompareRoot(r0, Heap::kExceptionRootIndex);
+ __ b(eq, &exception_returned);
+
+ ExternalReference pending_exception_address(
+ Isolate::kPendingExceptionAddress, isolate());
+
+ // Check that there is no pending exception, otherwise we
+ // should have returned the exception sentinel.
+ if (FLAG_debug_code) {
+ Label okay;
+ __ mov(r2, Operand(pending_exception_address));
+ __ ldr(r2, MemOperand(r2));
+ __ CompareRoot(r2, Heap::kTheHoleValueRootIndex);
+ // Cannot use check here as it attempts to generate call into runtime.
+ __ b(eq, &okay);
+ __ stop("Unexpected pending exception");
+ __ bind(&okay);
+ }
// Exit C frame and return.
// r0:r1: result
// sp: stack pointer
// fp: frame pointer
- // Callee-saved register r4 still holds argc.
+ // Callee-saved register r4 still holds argc.
__ LeaveExitFrame(save_doubles_, r4, true);
__ mov(pc, lr);
- // check if we should retry or throw exception
- Label retry;
- __ bind(&failure_returned);
- STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0);
- __ tst(r0, Operand(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize));
- __ b(eq, &retry);
+ // Handling of exception.
+ __ bind(&exception_returned);
// Retrieve the pending exception.
- __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
- isolate)));
- __ ldr(r0, MemOperand(ip));
+ __ mov(r2, Operand(pending_exception_address));
+ __ ldr(r0, MemOperand(r2));
// Clear the pending exception.
__ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
- __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
- isolate)));
- __ str(r3, MemOperand(ip));
+ __ str(r3, MemOperand(r2));
// Special handling of termination exceptions which are uncatchable
// by javascript code.
- __ LoadRoot(r3, Heap::kTerminationExceptionRootIndex);
- __ cmp(r0, r3);
- __ b(eq, throw_termination_exception);
-
- // Handle normal exception.
- __ jmp(throw_normal_exception);
-
- __ bind(&retry); // pass last failure (r0) as parameter (r0) when retrying
-}
-
-
-void CEntryStub::Generate(MacroAssembler* masm) {
- // Called from JavaScript; parameters are on stack as if calling JS function
- // r0: number of arguments including receiver
- // r1: pointer to builtin function
- // fp: frame pointer (restored after C call)
- // sp: stack pointer (restored as callee's sp after C call)
- // cp: current context (C callee-saved)
-
- ProfileEntryHookStub::MaybeCallEntryHook(masm);
-
- // Result returned in r0 or r0+r1 by default.
-
- // NOTE: Invocations of builtins may return failure objects
- // instead of a proper result. The builtin entry handles
- // this by performing a garbage collection and retrying the
- // builtin once.
-
- // Compute the argv pointer in a callee-saved register.
- __ add(r6, sp, Operand(r0, LSL, kPointerSizeLog2));
- __ sub(r6, r6, Operand(kPointerSize));
-
- // Enter the exit frame that transitions from JavaScript to C++.
- FrameAndConstantPoolScope scope(masm, StackFrame::MANUAL);
- __ EnterExitFrame(save_doubles_);
-
- // Set up argc and the builtin function in callee-saved registers.
- __ mov(r4, Operand(r0));
- __ mov(r5, Operand(r1));
-
- // r4: number of arguments (C callee-saved)
- // r5: pointer to builtin function (C callee-saved)
- // r6: pointer to first argument (C callee-saved)
-
- Label throw_normal_exception;
Label throw_termination_exception;
+ __ CompareRoot(r0, Heap::kTerminationExceptionRootIndex);
+ __ b(eq, &throw_termination_exception);
- // Call into the runtime system.
- GenerateCore(masm,
- &throw_normal_exception,
- &throw_termination_exception,
- false,
- false);
-
- // Do space-specific GC and retry runtime call.
- GenerateCore(masm,
- &throw_normal_exception,
- &throw_termination_exception,
- true,
- false);
-
- // Do full GC and retry runtime call one final time.
- Failure* failure = Failure::InternalError();
- __ mov(r0, Operand(reinterpret_cast<int32_t>(failure)));
- GenerateCore(masm,
- &throw_normal_exception,
- &throw_termination_exception,
- true,
- true);
-
- { FrameScope scope(masm, StackFrame::MANUAL);
- __ PrepareCallCFunction(0, r0);
- __ CallCFunction(
- ExternalReference::out_of_memory_function(masm->isolate()), 0, 0);
- }
+ // Handle normal exception.
+ __ Throw(r0);
__ bind(&throw_termination_exception);
__ ThrowUncatchable(r0);
-
- __ bind(&throw_normal_exception);
- __ Throw(r0);
}
@@ -1738,15 +1618,14 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// r2: receiver
// r3: argc
// r4: argv
- Isolate* isolate = masm->isolate();
int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
if (FLAG_enable_ool_constant_pool) {
- __ mov(r8, Operand(isolate->factory()->empty_constant_pool_array()));
+ __ mov(r8, Operand(isolate()->factory()->empty_constant_pool_array()));
}
__ mov(r7, Operand(Smi::FromInt(marker)));
__ mov(r6, Operand(Smi::FromInt(marker)));
__ mov(r5,
- Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate)));
+ Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
__ ldr(r5, MemOperand(r5));
__ mov(ip, Operand(-1)); // Push a bad frame pointer to fail if it is used.
__ stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() |
@@ -1758,7 +1637,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// If this is the outermost JS call, set js_entry_sp value.
Label non_outermost_js;
- ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate);
+ ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate());
__ mov(r5, Operand(ExternalReference(js_entry_sp)));
__ ldr(r6, MemOperand(r5));
__ cmp(r6, Operand::Zero());
@@ -1788,10 +1667,10 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// fp will be invalid because the PushTryHandler below sets it to 0 to
// signal the existence of the JSEntry frame.
__ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
- isolate)));
+ isolate())));
}
__ str(r0, MemOperand(ip));
- __ mov(r0, Operand(reinterpret_cast<int32_t>(Failure::Exception())));
+ __ LoadRoot(r0, Heap::kExceptionRootIndex);
__ b(&exit);
// Invoke: Link this frame into the handler chain. There's only one
@@ -1805,9 +1684,9 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// saved values before returning a failure to C.
// Clear any pending exceptions.
- __ mov(r5, Operand(isolate->factory()->the_hole_value()));
+ __ mov(r5, Operand(isolate()->factory()->the_hole_value()));
__ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
- isolate)));
+ isolate())));
__ str(r5, MemOperand(ip));
// Invoke the function by calling through JS entry trampoline builtin.
@@ -1822,10 +1701,10 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// r4: argv
if (is_construct) {
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
- isolate);
+ isolate());
__ mov(ip, Operand(construct_entry));
} else {
- ExternalReference entry(Builtins::kJSEntryTrampoline, isolate);
+ ExternalReference entry(Builtins::kJSEntryTrampoline, isolate());
__ mov(ip, Operand(entry));
}
__ ldr(ip, MemOperand(ip)); // deref address
@@ -1851,7 +1730,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// Restore the top frame descriptors from the stack.
__ pop(r3);
__ mov(ip,
- Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate)));
+ Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
__ str(r3, MemOperand(ip));
// Reset the stack to the callee saved registers.
@@ -2010,7 +1889,7 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
__ b(ne, &slow);
// Null is not instance of anything.
- __ cmp(scratch, Operand(masm->isolate()->factory()->null_value()));
+ __ cmp(scratch, Operand(isolate()->factory()->null_value()));
__ b(ne, &object_not_null);
__ mov(r0, Operand(Smi::FromInt(1)));
__ Ret(HasArgsInRegisters() ? 0 : 2);
@@ -2057,7 +1936,7 @@ void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
// -- r0 : key
// -- r1 : receiver
// -----------------------------------
- __ cmp(r0, Operand(masm->isolate()->factory()->prototype_string()));
+ __ cmp(r0, Operand(isolate()->factory()->prototype_string()));
__ b(ne, &miss);
receiver = r1;
} else {
@@ -2487,11 +2366,10 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
Register last_match_info_elements = no_reg; // will be r6;
// Ensure that a RegExp stack is allocated.
- Isolate* isolate = masm->isolate();
ExternalReference address_of_regexp_stack_memory_address =
- ExternalReference::address_of_regexp_stack_memory_address(isolate);
+ ExternalReference::address_of_regexp_stack_memory_address(isolate());
ExternalReference address_of_regexp_stack_memory_size =
- ExternalReference::address_of_regexp_stack_memory_size(isolate);
+ ExternalReference::address_of_regexp_stack_memory_size(isolate());
__ mov(r0, Operand(address_of_regexp_stack_memory_size));
__ ldr(r0, MemOperand(r0, 0));
__ cmp(r0, Operand::Zero());
@@ -2633,7 +2511,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// subject: Subject string
// regexp_data: RegExp data (FixedArray)
// All checks done. Now push arguments for native regexp code.
- __ IncrementCounter(isolate->counters()->regexp_entry_native(), 1, r0, r2);
+ __ IncrementCounter(isolate()->counters()->regexp_entry_native(), 1, r0, r2);
// Isolates: note we add an additional parameter here (isolate pointer).
const int kRegExpExecuteArguments = 9;
@@ -2644,7 +2522,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Arguments are before that on the stack or in registers.
// Argument 9 (sp[20]): Pass current isolate address.
- __ mov(r0, Operand(ExternalReference::isolate_address(isolate)));
+ __ mov(r0, Operand(ExternalReference::isolate_address(isolate())));
__ str(r0, MemOperand(sp, 5 * kPointerSize));
// Argument 8 (sp[16]): Indicate that this is a direct call from JavaScript.
@@ -2666,7 +2544,8 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Argument 5 (sp[4]): static offsets vector buffer.
__ mov(r0,
- Operand(ExternalReference::address_of_static_offsets_vector(isolate)));
+ Operand(ExternalReference::address_of_static_offsets_vector(
+ isolate())));
__ str(r0, MemOperand(sp, 1 * kPointerSize));
// For arguments 4 and 3 get string length, calculate start of string data and
@@ -2697,7 +2576,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Locate the code entry and call it.
__ add(r6, r6, Operand(Code::kHeaderSize - kHeapObjectTag));
- DirectCEntryStub stub;
+ DirectCEntryStub stub(isolate());
stub.GenerateCall(masm, r6);
__ LeaveExitFrame(false, no_reg, true);
@@ -2724,9 +2603,9 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// stack overflow (on the backtrack stack) was detected in RegExp code but
// haven't created the exception yet. Handle that in the runtime system.
// TODO(592): Rerunning the RegExp to get the stack overflow exception.
- __ mov(r1, Operand(isolate->factory()->the_hole_value()));
+ __ mov(r1, Operand(isolate()->factory()->the_hole_value()));
__ mov(r2, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
- isolate)));
+ isolate())));
__ ldr(r0, MemOperand(r2, 0));
__ cmp(r0, r1);
__ b(eq, &runtime);
@@ -2746,7 +2625,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ bind(&failure);
// For failure and exception return null.
- __ mov(r0, Operand(masm->isolate()->factory()->null_value()));
+ __ mov(r0, Operand(isolate()->factory()->null_value()));
__ add(sp, sp, Operand(4 * kPointerSize));
__ Ret();
@@ -2808,7 +2687,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Get the static offsets vector filled by the native regexp code.
ExternalReference address_of_static_offsets_vector =
- ExternalReference::address_of_static_offsets_vector(isolate);
+ ExternalReference::address_of_static_offsets_vector(isolate());
__ mov(r2, Operand(address_of_static_offsets_vector));
// r1: number of capture registers
@@ -2953,7 +2832,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
__ SmiTag(r0);
__ Push(r3, r2, r1, r0);
- CreateAllocationSiteStub create_stub;
+ CreateAllocationSiteStub create_stub(masm->isolate());
__ CallStub(&create_stub);
__ Pop(r3, r2, r1, r0);
@@ -2977,11 +2856,62 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
}
+static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
+ // Do not transform the receiver for strict mode functions.
+ __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
+ __ ldr(r4, FieldMemOperand(r3, SharedFunctionInfo::kCompilerHintsOffset));
+ __ tst(r4, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
+ kSmiTagSize)));
+ __ b(ne, cont);
+
+ // Do not transform the receiver for native (Compilerhints already in r3).
+ __ tst(r4, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
+ __ b(ne, cont);
+}
+
+
+static void EmitSlowCase(MacroAssembler* masm,
+ int argc,
+ Label* non_function) {
+ // Check for function proxy.
+ __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE));
+ __ b(ne, non_function);
+ __ push(r1); // put proxy as additional argument
+ __ mov(r0, Operand(argc + 1, RelocInfo::NONE32));
+ __ mov(r2, Operand::Zero());
+ __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY);
+ {
+ Handle<Code> adaptor =
+ masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
+ __ Jump(adaptor, RelocInfo::CODE_TARGET);
+ }
+
+ // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
+ // of the original receiver from the call site).
+ __ bind(non_function);
+ __ str(r1, MemOperand(sp, argc * kPointerSize));
+ __ mov(r0, Operand(argc)); // Set up the number of arguments.
+ __ mov(r2, Operand::Zero());
+ __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION);
+ __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+ RelocInfo::CODE_TARGET);
+}
+
+
+static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) {
+ // Wrap the receiver and patch it back onto the stack.
+ { FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
+ __ Push(r1, r3);
+ __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
+ __ pop(r1);
+ }
+ __ str(r0, MemOperand(sp, argc * kPointerSize));
+ __ jmp(cont);
+}
+
+
void CallFunctionStub::Generate(MacroAssembler* masm) {
// r1 : the function to call
- // r2 : feedback vector
- // r3 : (only if r2 is not the megamorphic symbol) slot in feedback
- // vector (Smi)
Label slow, non_function, wrap, cont;
if (NeedsChecks()) {
@@ -2992,36 +2922,20 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// Goto slow case if we do not have a function.
__ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE);
__ b(ne, &slow);
-
- if (RecordCallTarget()) {
- GenerateRecordCallTarget(masm);
- // Type information was updated. Because we may call Array, which
- // expects either undefined or an AllocationSite in ebx we need
- // to set ebx to undefined.
- __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
- }
}
// Fast-case: Invoke the function now.
// r1: pushed function
- ParameterCount actual(argc_);
+ int argc = argc_;
+ ParameterCount actual(argc);
if (CallAsMethod()) {
if (NeedsChecks()) {
- // Do not transform the receiver for strict mode functions.
- __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
- __ ldr(r4, FieldMemOperand(r3, SharedFunctionInfo::kCompilerHintsOffset));
- __ tst(r4, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
- kSmiTagSize)));
- __ b(ne, &cont);
-
- // Do not transform the receiver for native (Compilerhints already in r3).
- __ tst(r4, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
- __ b(ne, &cont);
+ EmitContinueIfStrictOrNative(masm, &cont);
}
// Compute the receiver in sloppy mode.
- __ ldr(r3, MemOperand(sp, argc_ * kPointerSize));
+ __ ldr(r3, MemOperand(sp, argc * kPointerSize));
if (NeedsChecks()) {
__ JumpIfSmi(r3, &wrap);
@@ -3033,55 +2947,18 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
__ bind(&cont);
}
+
__ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper());
if (NeedsChecks()) {
// Slow-case: Non-function called.
__ bind(&slow);
- if (RecordCallTarget()) {
- // If there is a call target cache, mark it megamorphic in the
- // non-function case. MegamorphicSentinel is an immortal immovable
- // object (megamorphic symbol) so no write barrier is needed.
- ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
- masm->isolate()->heap()->megamorphic_symbol());
- __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3));
- __ LoadRoot(ip, Heap::kMegamorphicSymbolRootIndex);
- __ str(ip, FieldMemOperand(r5, FixedArray::kHeaderSize));
- }
- // Check for function proxy.
- __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE));
- __ b(ne, &non_function);
- __ push(r1); // put proxy as additional argument
- __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE32));
- __ mov(r2, Operand::Zero());
- __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY);
- {
- Handle<Code> adaptor =
- masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
- __ Jump(adaptor, RelocInfo::CODE_TARGET);
- }
-
- // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
- // of the original receiver from the call site).
- __ bind(&non_function);
- __ str(r1, MemOperand(sp, argc_ * kPointerSize));
- __ mov(r0, Operand(argc_)); // Set up the number of arguments.
- __ mov(r2, Operand::Zero());
- __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION);
- __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
- RelocInfo::CODE_TARGET);
+ EmitSlowCase(masm, argc, &non_function);
}
if (CallAsMethod()) {
__ bind(&wrap);
- // Wrap the receiver and patch it back onto the stack.
- { FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
- __ Push(r1, r3);
- __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
- __ pop(r1);
- }
- __ str(r0, MemOperand(sp, argc_ * kPointerSize));
- __ jmp(&cont);
+ EmitWrapCase(masm, argc, &cont);
}
}
@@ -3145,11 +3022,114 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
__ bind(&do_call);
// Set expected number of arguments to zero (not changing r0).
__ mov(r2, Operand::Zero());
- __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+ __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET);
}
+static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
+ __ ldr(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+ __ ldr(vector, FieldMemOperand(vector,
+ JSFunction::kSharedFunctionInfoOffset));
+ __ ldr(vector, FieldMemOperand(vector,
+ SharedFunctionInfo::kFeedbackVectorOffset));
+}
+
+
+void CallICStub::Generate(MacroAssembler* masm) {
+ // r1 - function
+ // r3 - slot id (Smi)
+ Label extra_checks_or_miss, slow_start;
+ Label slow, non_function, wrap, cont;
+ Label have_js_function;
+ int argc = state_.arg_count();
+ ParameterCount actual(argc);
+
+ EmitLoadTypeFeedbackVector(masm, r2);
+
+ // The checks. First, does r1 match the recorded monomorphic target?
+ __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
+ __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize));
+ __ cmp(r1, r4);
+ __ b(ne, &extra_checks_or_miss);
+
+ __ bind(&have_js_function);
+ if (state_.CallAsMethod()) {
+ EmitContinueIfStrictOrNative(masm, &cont);
+ // Compute the receiver in sloppy mode.
+ __ ldr(r3, MemOperand(sp, argc * kPointerSize));
+
+ __ JumpIfSmi(r3, &wrap);
+ __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE);
+ __ b(lt, &wrap);
+
+ __ bind(&cont);
+ }
+
+ __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper());
+
+ __ bind(&slow);
+ EmitSlowCase(masm, argc, &non_function);
+
+ if (state_.CallAsMethod()) {
+ __ bind(&wrap);
+ EmitWrapCase(masm, argc, &cont);
+ }
+
+ __ bind(&extra_checks_or_miss);
+ Label miss;
+
+ __ CompareRoot(r4, Heap::kMegamorphicSymbolRootIndex);
+ __ b(eq, &slow_start);
+ __ CompareRoot(r4, Heap::kUninitializedSymbolRootIndex);
+ __ b(eq, &miss);
+
+ if (!FLAG_trace_ic) {
+ // We are going megamorphic, and we don't want to visit the runtime.
+ __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
+ __ LoadRoot(ip, Heap::kMegamorphicSymbolRootIndex);
+ __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
+ __ jmp(&slow_start);
+ }
+
+ // We are here because tracing is on or we are going monomorphic.
+ __ bind(&miss);
+ GenerateMiss(masm);
+
+ // the slow case
+ __ bind(&slow_start);
+ // Check that the function is really a JavaScript function.
+ // r1: pushed function (to be verified)
+ __ JumpIfSmi(r1, &non_function);
+
+ // Goto slow case if we do not have a function.
+ __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE);
+ __ b(ne, &slow);
+ __ jmp(&have_js_function);
+}
+
+
+void CallICStub::GenerateMiss(MacroAssembler* masm) {
+ // Get the receiver of the function from the stack; 1 ~ return address.
+ __ ldr(r4, MemOperand(sp, (state_.arg_count() + 1) * kPointerSize));
+
+ {
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+
+ // Push the receiver and the function and feedback info.
+ __ Push(r4, r1, r2, r3);
+
+ // Call the entry.
+ ExternalReference miss = ExternalReference(IC_Utility(IC::kCallIC_Miss),
+ masm->isolate());
+ __ CallExternalReference(miss, 4);
+
+ // Move result to edi and exit the internal frame.
+ __ mov(r1, r0);
+ }
+}
+
+
// StringCharCodeAtGenerator
void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
Label flat_string;
@@ -3512,10 +3492,8 @@ void SubStringStub::Generate(MacroAssembler* masm) {
// Make sure first argument is a string.
__ ldr(r0, MemOperand(sp, kStringOffset));
- // Do a JumpIfSmi, but fold its jump into the subsequent string test.
- __ SmiTst(r0);
- Condition is_string = masm->IsObjectStringType(r0, r1, ne);
- ASSERT(is_string == eq);
+ __ JumpIfSmi(r0, &runtime);
+ Condition is_string = masm->IsObjectStringType(r0, r1);
__ b(NegateCondition(is_string), &runtime);
Label single_char;
@@ -3673,7 +3651,7 @@ void SubStringStub::Generate(MacroAssembler* masm) {
masm, r1, r5, r2, r3, r4, r6, r9, DEST_ALWAYS_ALIGNED);
__ bind(&return_r0);
- Counters* counters = masm->isolate()->counters();
+ Counters* counters = isolate()->counters();
__ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
__ Drop(3);
__ Ret();
@@ -3808,7 +3786,7 @@ void StringCompareStub::GenerateAsciiCharsCompareLoop(
void StringCompareStub::Generate(MacroAssembler* masm) {
Label runtime;
- Counters* counters = masm->isolate()->counters();
+ Counters* counters = isolate()->counters();
// Stack frame on entry.
// sp[0]: right string
@@ -3842,223 +3820,17 @@ void StringCompareStub::Generate(MacroAssembler* masm) {
}
-void ArrayPushStub::Generate(MacroAssembler* masm) {
- Register receiver = r0;
- Register scratch = r1;
-
- int argc = arguments_count();
-
- if (argc == 0) {
- // Nothing to do, just return the length.
- __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ Drop(argc + 1);
- __ Ret();
- return;
- }
-
- Isolate* isolate = masm->isolate();
-
- if (argc != 1) {
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- Label call_builtin, attempt_to_grow_elements, with_write_barrier;
-
- Register elements = r6;
- Register end_elements = r5;
- // Get the elements array of the object.
- __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- // Check that the elements are in fast mode and writable.
- __ CheckMap(elements,
- scratch,
- Heap::kFixedArrayMapRootIndex,
- &call_builtin,
- DONT_DO_SMI_CHECK);
- }
-
- // Get the array's length into scratch and calculate new length.
- __ ldr(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ add(scratch, scratch, Operand(Smi::FromInt(argc)));
-
- // Get the elements' length.
- __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset));
-
- // Check if we could survive without allocation.
- __ cmp(scratch, r4);
-
- const int kEndElementsOffset =
- FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize;
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- __ b(gt, &attempt_to_grow_elements);
-
- // Check if value is a smi.
- __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize));
- __ JumpIfNotSmi(r4, &with_write_barrier);
-
- // Store the value.
- // We may need a register containing the address end_elements below, so
- // write back the value in end_elements.
- __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(scratch));
- __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex));
- } else {
- // Check if we could survive without allocation.
- __ cmp(scratch, r4);
- __ b(gt, &call_builtin);
-
- __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize));
- __ StoreNumberToDoubleElements(r4, scratch, elements, r5, d0,
- &call_builtin, argc * kDoubleSize);
- }
-
- // Save new length.
- __ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ Drop(argc + 1);
- __ mov(r0, scratch);
- __ Ret();
-
- if (IsFastDoubleElementsKind(elements_kind())) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ bind(&with_write_barrier);
-
- if (IsFastSmiElementsKind(elements_kind())) {
- if (FLAG_trace_elements_transitions) __ jmp(&call_builtin);
-
- __ ldr(r9, FieldMemOperand(r4, HeapObject::kMapOffset));
- __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
- __ cmp(r9, ip);
- __ b(eq, &call_builtin);
-
- ElementsKind target_kind = IsHoleyElementsKind(elements_kind())
- ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
- __ ldr(r3, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
- __ ldr(r3, FieldMemOperand(r3, GlobalObject::kNativeContextOffset));
- __ ldr(r3, ContextOperand(r3, Context::JS_ARRAY_MAPS_INDEX));
- const int header_size = FixedArrayBase::kHeaderSize;
- // Verify that the object can be transitioned in place.
- const int origin_offset = header_size + elements_kind() * kPointerSize;
- __ ldr(r2, FieldMemOperand(receiver, origin_offset));
- __ ldr(ip, FieldMemOperand(r3, HeapObject::kMapOffset));
- __ cmp(r2, ip);
- __ b(ne, &call_builtin);
-
- const int target_offset = header_size + target_kind * kPointerSize;
- __ ldr(r3, FieldMemOperand(r3, target_offset));
- __ mov(r2, receiver);
- ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
- masm, DONT_TRACK_ALLOCATION_SITE, NULL);
- }
-
- // Save new length.
- __ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
-
- // Store the value.
- // We may need a register containing the address end_elements below, so write
- // back the value in end_elements.
- __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(scratch));
- __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex));
-
- __ RecordWrite(elements,
- end_elements,
- r4,
- kLRHasNotBeenSaved,
- kDontSaveFPRegs,
- EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
- __ Drop(argc + 1);
- __ mov(r0, scratch);
- __ Ret();
-
- __ bind(&attempt_to_grow_elements);
- // scratch: array's length + 1.
-
- if (!FLAG_inline_new) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ ldr(r2, MemOperand(sp, (argc - 1) * kPointerSize));
- // Growing elements that are SMI-only requires special handling in case the
- // new element is non-Smi. For now, delegate to the builtin.
- if (IsFastSmiElementsKind(elements_kind())) {
- __ JumpIfNotSmi(r2, &call_builtin);
- }
-
- // We could be lucky and the elements array could be at the top of new-space.
- // In this case we can just grow it in place by moving the allocation pointer
- // up.
- ExternalReference new_space_allocation_top =
- ExternalReference::new_space_allocation_top_address(isolate);
- ExternalReference new_space_allocation_limit =
- ExternalReference::new_space_allocation_limit_address(isolate);
-
- const int kAllocationDelta = 4;
- ASSERT(kAllocationDelta >= argc);
- // Load top and check if it is the end of elements.
- __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(scratch));
- __ add(end_elements, end_elements, Operand(kEndElementsOffset));
- __ mov(r4, Operand(new_space_allocation_top));
- __ ldr(r3, MemOperand(r4));
- __ cmp(end_elements, r3);
- __ b(ne, &call_builtin);
-
- __ mov(r9, Operand(new_space_allocation_limit));
- __ ldr(r9, MemOperand(r9));
- __ add(r3, r3, Operand(kAllocationDelta * kPointerSize));
- __ cmp(r3, r9);
- __ b(hi, &call_builtin);
-
- // We fit and could grow elements.
- // Update new_space_allocation_top.
- __ str(r3, MemOperand(r4));
- // Push the argument.
- __ str(r2, MemOperand(end_elements));
- // Fill the rest with holes.
- __ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
- for (int i = 1; i < kAllocationDelta; i++) {
- __ str(r3, MemOperand(end_elements, i * kPointerSize));
- }
-
- // Update elements' and array's sizes.
- __ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset));
- __ add(r4, r4, Operand(Smi::FromInt(kAllocationDelta)));
- __ str(r4, FieldMemOperand(elements, FixedArray::kLengthOffset));
-
- // Elements are in new space, so write barrier is not required.
- __ Drop(argc + 1);
- __ mov(r0, scratch);
- __ Ret();
-
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
-}
-
-
void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r1 : left
// -- r0 : right
// -- lr : return address
// -----------------------------------
- Isolate* isolate = masm->isolate();
// Load r2 with the allocation site. We stick an undefined dummy value here
// and replace it with the real allocation site later when we instantiate this
// stub in BinaryOpICWithAllocationSiteStub::GetCodeCopyFromTemplate().
- __ Move(r2, handle(isolate->heap()->undefined_value()));
+ __ Move(r2, handle(isolate()->heap()->undefined_value()));
// Make sure that we actually patched the allocation site.
if (FLAG_debug_code) {
@@ -4074,7 +3846,7 @@ void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
// Tail call into the stub that handles binary operations with allocation
// sites.
- BinaryOpWithAllocationSiteStub stub(state_);
+ BinaryOpWithAllocationSiteStub stub(isolate(), state_);
__ TailCallStub(&stub);
}
@@ -4152,9 +3924,9 @@ void ICCompareStub::GenerateNumbers(MacroAssembler* masm) {
__ bind(&unordered);
__ bind(&generic_stub);
- ICCompareStub stub(op_, CompareIC::GENERIC, CompareIC::GENERIC,
+ ICCompareStub stub(isolate(), op_, CompareIC::GENERIC, CompareIC::GENERIC,
CompareIC::GENERIC);
- __ Jump(stub.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
+ __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
__ bind(&maybe_undefined1);
if (Token::IsOrderedRelationalCompareOp(op_)) {
@@ -4377,7 +4149,7 @@ void ICCompareStub::GenerateMiss(MacroAssembler* masm) {
{
// Call the runtime system in a fresh internal frame.
ExternalReference miss =
- ExternalReference(IC_Utility(IC::kCompareIC_Miss), masm->isolate());
+ ExternalReference(IC_Utility(IC::kCompareIC_Miss), isolate());
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ Push(r1, r0);
@@ -4409,7 +4181,7 @@ void DirectCEntryStub::Generate(MacroAssembler* masm) {
void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
Register target) {
intptr_t code =
- reinterpret_cast<intptr_t>(GetCode(masm->isolate()).location());
+ reinterpret_cast<intptr_t>(GetCode().location());
__ Move(ip, target);
__ mov(lr, Operand(code, RelocInfo::CODE_TARGET));
__ blx(lr); // Call the stub.
@@ -4485,7 +4257,7 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
__ stm(db_w, sp, spill_mask);
__ ldr(r0, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
__ mov(r1, Operand(Handle<Name>(name)));
- NameDictionaryLookupStub stub(NEGATIVE_LOOKUP);
+ NameDictionaryLookupStub stub(masm->isolate(), NEGATIVE_LOOKUP);
__ CallStub(&stub);
__ cmp(r0, Operand::Zero());
__ ldm(ia_w, sp, spill_mask);
@@ -4561,7 +4333,7 @@ void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
__ Move(r0, elements);
__ Move(r1, name);
}
- NameDictionaryLookupStub stub(POSITIVE_LOOKUP);
+ NameDictionaryLookupStub stub(masm->isolate(), POSITIVE_LOOKUP);
__ CallStub(&stub);
__ cmp(r0, Operand::Zero());
__ mov(scratch2, Operand(r2));
@@ -4665,11 +4437,11 @@ void NameDictionaryLookupStub::Generate(MacroAssembler* masm) {
void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
Isolate* isolate) {
- StoreBufferOverflowStub stub1(kDontSaveFPRegs);
- stub1.GetCode(isolate);
+ StoreBufferOverflowStub stub1(isolate, kDontSaveFPRegs);
+ stub1.GetCode();
// Hydrogen code stubs need stub2 at snapshot time.
- StoreBufferOverflowStub stub2(kSaveFPRegs);
- stub2.GetCode(isolate);
+ StoreBufferOverflowStub stub2(isolate, kSaveFPRegs);
+ stub2.GetCode();
}
@@ -4774,12 +4546,11 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
__ Move(address, regs_.address());
__ Move(r0, regs_.object());
__ Move(r1, address);
- __ mov(r2, Operand(ExternalReference::isolate_address(masm->isolate())));
+ __ mov(r2, Operand(ExternalReference::isolate_address(isolate())));
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(
- ExternalReference::incremental_marking_record_write_function(
- masm->isolate()),
+ ExternalReference::incremental_marking_record_write_function(isolate()),
argument_count);
regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode_);
}
@@ -4934,8 +4705,8 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
- CEntryStub ces(1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
- __ Call(ces.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
+ CEntryStub ces(isolate(), 1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
+ __ Call(ces.GetCode(), RelocInfo::CODE_TARGET);
int parameter_count_offset =
StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
__ ldr(r1, MemOperand(fp, parameter_count_offset));
@@ -4951,8 +4722,9 @@ void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
if (masm->isolate()->function_entry_hook() != NULL) {
- PredictableCodeSizeScope predictable(masm, 4 * Assembler::kInstrSize);
- ProfileEntryHookStub stub;
+ ProfileEntryHookStub stub(masm->isolate());
+ int code_size = masm->CallStubSize(&stub) + 2 * Assembler::kInstrSize;
+ PredictableCodeSizeScope predictable(masm, code_size);
__ push(lr);
__ CallStub(&stub);
__ pop(lr);
@@ -4998,18 +4770,18 @@ void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
#if V8_HOST_ARCH_ARM
int32_t entry_hook =
- reinterpret_cast<int32_t>(masm->isolate()->function_entry_hook());
+ reinterpret_cast<int32_t>(isolate()->function_entry_hook());
__ mov(ip, Operand(entry_hook));
#else
// Under the simulator we need to indirect the entry hook through a
// trampoline function at a known address.
// It additionally takes an isolate as a third parameter
- __ mov(r2, Operand(ExternalReference::isolate_address(masm->isolate())));
+ __ mov(r2, Operand(ExternalReference::isolate_address(isolate())));
ApiFunction dispatcher(FUNCTION_ADDR(EntryHookTrampoline));
__ mov(ip, Operand(ExternalReference(&dispatcher,
ExternalReference::BUILTIN_CALL,
- masm->isolate())));
+ isolate())));
#endif
__ Call(ip);
@@ -5027,7 +4799,7 @@ template<class T>
static void CreateArrayDispatch(MacroAssembler* masm,
AllocationSiteOverrideMode mode) {
if (mode == DISABLE_ALLOCATION_SITES) {
- T stub(GetInitialFastElementsKind(), mode);
+ T stub(masm->isolate(), GetInitialFastElementsKind(), mode);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
int last_index = GetSequenceIndexFromFastElementsKind(
@@ -5035,7 +4807,7 @@ static void CreateArrayDispatch(MacroAssembler* masm,
for (int i = 0; i <= last_index; ++i) {
ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
__ cmp(r3, Operand(kind));
- T stub(kind);
+ T stub(masm->isolate(), kind);
__ TailCallStub(&stub, eq);
}
@@ -5077,12 +4849,14 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
ElementsKind initial = GetInitialFastElementsKind();
ElementsKind holey_initial = GetHoleyElementsKind(initial);
- ArraySingleArgumentConstructorStub stub_holey(holey_initial,
+ ArraySingleArgumentConstructorStub stub_holey(masm->isolate(),
+ holey_initial,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub_holey);
__ bind(&normal_sequence);
- ArraySingleArgumentConstructorStub stub(initial,
+ ArraySingleArgumentConstructorStub stub(masm->isolate(),
+ initial,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
@@ -5110,7 +4884,7 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
for (int i = 0; i <= last_index; ++i) {
ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
__ cmp(r3, Operand(kind));
- ArraySingleArgumentConstructorStub stub(kind);
+ ArraySingleArgumentConstructorStub stub(masm->isolate(), kind);
__ TailCallStub(&stub, eq);
}
@@ -5128,11 +4902,11 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
TERMINAL_FAST_ELEMENTS_KIND);
for (int i = 0; i <= to_index; ++i) {
ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
- T stub(kind);
- stub.GetCode(isolate);
+ T stub(isolate, kind);
+ stub.GetCode();
if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
- T stub1(kind, DISABLE_ALLOCATION_SITES);
- stub1.GetCode(isolate);
+ T stub1(isolate, kind, DISABLE_ALLOCATION_SITES);
+ stub1.GetCode();
}
}
}
@@ -5153,12 +4927,12 @@ void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
for (int i = 0; i < 2; i++) {
// For internal arrays we only need a few things
- InternalArrayNoArgumentConstructorStub stubh1(kinds[i]);
- stubh1.GetCode(isolate);
- InternalArraySingleArgumentConstructorStub stubh2(kinds[i]);
- stubh2.GetCode(isolate);
- InternalArrayNArgumentsConstructorStub stubh3(kinds[i]);
- stubh3.GetCode(isolate);
+ InternalArrayNoArgumentConstructorStub stubh1(isolate, kinds[i]);
+ stubh1.GetCode();
+ InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]);
+ stubh2.GetCode();
+ InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]);
+ stubh3.GetCode();
}
}
@@ -5236,10 +5010,10 @@ void InternalArrayConstructorStub::GenerateCase(
MacroAssembler* masm, ElementsKind kind) {
__ cmp(r0, Operand(1));
- InternalArrayNoArgumentConstructorStub stub0(kind);
+ InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
__ TailCallStub(&stub0, lo);
- InternalArrayNArgumentsConstructorStub stubN(kind);
+ InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
__ TailCallStub(&stubN, hi);
if (IsFastPackedElementsKind(kind)) {
@@ -5249,11 +5023,11 @@ void InternalArrayConstructorStub::GenerateCase(
__ cmp(r3, Operand::Zero());
InternalArraySingleArgumentConstructorStub
- stub1_holey(GetHoleyElementsKind(kind));
+ stub1_holey(isolate(), GetHoleyElementsKind(kind));
__ TailCallStub(&stub1_holey, ne);
}
- InternalArraySingleArgumentConstructorStub stub1(kind);
+ InternalArraySingleArgumentConstructorStub stub1(isolate(), kind);
__ TailCallStub(&stub1);
}
@@ -5342,8 +5116,6 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(FCA::kHolderIndex == 0);
STATIC_ASSERT(FCA::kArgsLength == 7);
- Isolate* isolate = masm->isolate();
-
// context save
__ push(context);
// load context from callee
@@ -5365,7 +5137,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
__ push(scratch);
// isolate
__ mov(scratch,
- Operand(ExternalReference::isolate_address(isolate)));
+ Operand(ExternalReference::isolate_address(isolate())));
__ push(scratch);
// holder
__ push(holder);
@@ -5377,7 +5149,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
// it's not controlled by GC.
const int kApiStackSpace = 4;
- FrameAndConstantPoolScope frame_scope(masm, StackFrame::MANUAL);
+ FrameScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, kApiStackSpace);
ASSERT(!api_function_address.is(r0) && !scratch.is(r0));
@@ -5397,11 +5169,8 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
__ str(ip, MemOperand(r0, 3 * kPointerSize));
const int kStackUnwindSpace = argc + FCA::kArgsLength + 1;
- Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
- ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
- ApiFunction thunk_fun(thunk_address);
- ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
- masm->isolate());
+ ExternalReference thunk_ref =
+ ExternalReference::invoke_function_callback(isolate());
AllowExternalCallThatCantCauseGC scope(masm);
MemOperand context_restore_operand(
@@ -5437,7 +5206,7 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
__ add(r1, r0, Operand(1 * kPointerSize)); // r1 = PCA
const int kApiStackSpace = 1;
- FrameAndConstantPoolScope frame_scope(masm, StackFrame::MANUAL);
+ FrameScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, kApiStackSpace);
// Create PropertyAccessorInfo instance on the stack above the exit frame with
@@ -5447,12 +5216,8 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
- Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
- ExternalReference::Type thunk_type =
- ExternalReference::PROFILING_GETTER_CALL;
- ApiFunction thunk_fun(thunk_address);
- ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
- masm->isolate());
+ ExternalReference thunk_ref =
+ ExternalReference::invoke_accessor_getter_callback(isolate());
__ CallApiFunctionAndReturn(api_function_address,
thunk_ref,
kStackUnwindSpace,
diff --git a/deps/v8/src/arm/code-stubs-arm.h b/deps/v8/src/arm/code-stubs-arm.h
index ef78802bef..3237b3af41 100644
--- a/deps/v8/src/arm/code-stubs-arm.h
+++ b/deps/v8/src/arm/code-stubs-arm.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM_CODE_STUBS_ARM_H_
#define V8_ARM_CODE_STUBS_ARM_H_
@@ -39,8 +16,8 @@ void ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code);
class StoreBufferOverflowStub: public PlatformCodeStub {
public:
- explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp)
- : save_doubles_(save_fp) {}
+ StoreBufferOverflowStub(Isolate* isolate, SaveFPRegsMode save_fp)
+ : PlatformCodeStub(isolate), save_doubles_(save_fp) {}
void Generate(MacroAssembler* masm);
@@ -91,7 +68,7 @@ class StringHelper : public AllStatic {
class SubStringStub: public PlatformCodeStub {
public:
- SubStringStub() {}
+ explicit SubStringStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
private:
Major MajorKey() { return SubString; }
@@ -104,7 +81,7 @@ class SubStringStub: public PlatformCodeStub {
class StringCompareStub: public PlatformCodeStub {
public:
- StringCompareStub() { }
+ explicit StringCompareStub(Isolate* isolate) : PlatformCodeStub(isolate) { }
// Compares two flat ASCII strings and returns result in r0.
static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
@@ -144,10 +121,12 @@ class StringCompareStub: public PlatformCodeStub {
// so you don't have to set up the frame.
class WriteInt32ToHeapNumberStub : public PlatformCodeStub {
public:
- WriteInt32ToHeapNumberStub(Register the_int,
+ WriteInt32ToHeapNumberStub(Isolate* isolate,
+ Register the_int,
Register the_heap_number,
Register scratch)
- : the_int_(the_int),
+ : PlatformCodeStub(isolate),
+ the_int_(the_int),
the_heap_number_(the_heap_number),
scratch_(scratch) { }
@@ -177,12 +156,14 @@ class WriteInt32ToHeapNumberStub : public PlatformCodeStub {
class RecordWriteStub: public PlatformCodeStub {
public:
- RecordWriteStub(Register object,
+ RecordWriteStub(Isolate* isolate,
+ Register object,
Register value,
Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode)
- : object_(object),
+ : PlatformCodeStub(isolate),
+ object_(object),
value_(value),
address_(address),
remembered_set_action_(remembered_set_action),
@@ -363,7 +344,7 @@ class RecordWriteStub: public PlatformCodeStub {
// moved by GC
class DirectCEntryStub: public PlatformCodeStub {
public:
- DirectCEntryStub() {}
+ explicit DirectCEntryStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
void Generate(MacroAssembler* masm);
void GenerateCall(MacroAssembler* masm, Register target);
@@ -379,7 +360,8 @@ class NameDictionaryLookupStub: public PlatformCodeStub {
public:
enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
- explicit NameDictionaryLookupStub(LookupMode mode) : mode_(mode) { }
+ NameDictionaryLookupStub(Isolate* isolate, LookupMode mode)
+ : PlatformCodeStub(isolate), mode_(mode) { }
void Generate(MacroAssembler* masm);
diff --git a/deps/v8/src/arm/codegen-arm.cc b/deps/v8/src/arm/codegen-arm.cc
index cfc9dfec4d..8a46006eb9 100644
--- a/deps/v8/src/arm/codegen-arm.cc
+++ b/deps/v8/src/arm/codegen-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -102,13 +79,11 @@ UnaryMathFunction CreateExpFunction() {
#if defined(V8_HOST_ARCH_ARM)
OS::MemCopyUint8Function CreateMemCopyUint8Function(
- OS::MemCopyUint8Function stub) {
+ OS::MemCopyUint8Function stub) {
#if defined(USE_SIMULATOR)
return stub;
#else
- if (Serializer::enabled() || !CpuFeatures::IsSupported(UNALIGNED_ACCESSES)) {
- return stub;
- }
+ if (!CpuFeatures::IsSupported(UNALIGNED_ACCESSES)) return stub;
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, &actual_size, true));
if (buffer == NULL) return stub;
@@ -260,13 +235,11 @@ OS::MemCopyUint8Function CreateMemCopyUint8Function(
// Convert 8 to 16. The number of character to copy must be at least 8.
OS::MemCopyUint16Uint8Function CreateMemCopyUint16Uint8Function(
- OS::MemCopyUint16Uint8Function stub) {
+ OS::MemCopyUint16Uint8Function stub) {
#if defined(USE_SIMULATOR)
return stub;
#else
- if (Serializer::enabled() || !CpuFeatures::IsSupported(UNALIGNED_ACCESSES)) {
- return stub;
- }
+ if (!CpuFeatures::IsSupported(UNALIGNED_ACCESSES)) return stub;
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, &actual_size, true));
if (buffer == NULL) return stub;
@@ -849,47 +822,46 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
static const uint32_t kCodeAgePatchFirstInstruction = 0xe24f0008;
#endif
-static byte* GetNoCodeAgeSequence(uint32_t* length) {
- // The sequence of instructions that is patched out for aging code is the
- // following boilerplate stack-building prologue that is found in FUNCTIONS
- static bool initialized = false;
- static uint32_t sequence[kNoCodeAgeSequenceLength];
- byte* byte_sequence = reinterpret_cast<byte*>(sequence);
- *length = kNoCodeAgeSequenceLength * Assembler::kInstrSize;
- if (!initialized) {
- // Since patcher is a large object, allocate it dynamically when needed,
- // to avoid overloading the stack in stress conditions.
- SmartPointer<CodePatcher>
- patcher(new CodePatcher(byte_sequence, kNoCodeAgeSequenceLength));
- PredictableCodeSizeScope scope(patcher->masm(), *length);
- patcher->masm()->PushFixedFrame(r1);
- patcher->masm()->nop(ip.code());
- patcher->masm()->add(
- fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
- initialized = true;
- }
- return byte_sequence;
+CodeAgingHelper::CodeAgingHelper() {
+ ASSERT(young_sequence_.length() == kNoCodeAgeSequenceLength);
+ // Since patcher is a large object, allocate it dynamically when needed,
+ // to avoid overloading the stack in stress conditions.
+ // DONT_FLUSH is used because the CodeAgingHelper is initialized early in
+ // the process, before ARM simulator ICache is setup.
+ SmartPointer<CodePatcher> patcher(
+ new CodePatcher(young_sequence_.start(),
+ young_sequence_.length() / Assembler::kInstrSize,
+ CodePatcher::DONT_FLUSH));
+ PredictableCodeSizeScope scope(patcher->masm(), young_sequence_.length());
+ patcher->masm()->PushFixedFrame(r1);
+ patcher->masm()->nop(ip.code());
+ patcher->masm()->add(
+ fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
+}
+
+
+#ifdef DEBUG
+bool CodeAgingHelper::IsOld(byte* candidate) const {
+ return Memory::uint32_at(candidate) == kCodeAgePatchFirstInstruction;
}
+#endif
-bool Code::IsYoungSequence(byte* sequence) {
- uint32_t young_length;
- byte* young_sequence = GetNoCodeAgeSequence(&young_length);
- bool result = !memcmp(sequence, young_sequence, young_length);
- ASSERT(result ||
- Memory::uint32_at(sequence) == kCodeAgePatchFirstInstruction);
+bool Code::IsYoungSequence(Isolate* isolate, byte* sequence) {
+ bool result = isolate->code_aging_helper()->IsYoung(sequence);
+ ASSERT(result || isolate->code_aging_helper()->IsOld(sequence));
return result;
}
-void Code::GetCodeAgeAndParity(byte* sequence, Age* age,
+void Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
MarkingParity* parity) {
- if (IsYoungSequence(sequence)) {
+ if (IsYoungSequence(isolate, sequence)) {
*age = kNoAgeCodeAge;
*parity = NO_MARKING_PARITY;
} else {
Address target_address = Memory::Address_at(
- sequence + Assembler::kInstrSize * (kNoCodeAgeSequenceLength - 1));
+ sequence + (kNoCodeAgeSequenceLength - Assembler::kInstrSize));
Code* stub = GetCodeFromTargetAddress(target_address);
GetCodeAgeAndParity(stub, age, parity);
}
@@ -900,10 +872,9 @@ void Code::PatchPlatformCodeAge(Isolate* isolate,
byte* sequence,
Code::Age age,
MarkingParity parity) {
- uint32_t young_length;
- byte* young_sequence = GetNoCodeAgeSequence(&young_length);
+ uint32_t young_length = isolate->code_aging_helper()->young_sequence_length();
if (age == kNoAgeCodeAge) {
- CopyBytes(sequence, young_sequence, young_length);
+ isolate->code_aging_helper()->CopyYoungSequenceTo(sequence);
CPU::FlushICache(sequence, young_length);
} else {
Code* stub = GetCodeAgeStub(isolate, age, parity);
diff --git a/deps/v8/src/arm/codegen-arm.h b/deps/v8/src/arm/codegen-arm.h
index 0bf7ccadca..2fc8eb3f0a 100644
--- a/deps/v8/src/arm/codegen-arm.h
+++ b/deps/v8/src/arm/codegen-arm.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM_CODEGEN_ARM_H_
#define V8_ARM_CODEGEN_ARM_H_
diff --git a/deps/v8/src/arm/constants-arm.cc b/deps/v8/src/arm/constants-arm.cc
index 7d59a84b1d..676239f829 100644
--- a/deps/v8/src/arm/constants-arm.cc
+++ b/deps/v8/src/arm/constants-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/arm/constants-arm.h b/deps/v8/src/arm/constants-arm.h
index 14f4705cbd..5bace505fa 100644
--- a/deps/v8/src/arm/constants-arm.h
+++ b/deps/v8/src/arm/constants-arm.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM_CONSTANTS_ARM_H_
#define V8_ARM_CONSTANTS_ARM_H_
diff --git a/deps/v8/src/arm/cpu-arm.cc b/deps/v8/src/arm/cpu-arm.cc
index 20c6a5dcce..083d9b39eb 100644
--- a/deps/v8/src/arm/cpu-arm.cc
+++ b/deps/v8/src/arm/cpu-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2006-2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// CPU specific code for arm independent of OS goes here.
#ifdef __arm__
@@ -46,16 +23,6 @@
namespace v8 {
namespace internal {
-void CPU::SetUp() {
- CpuFeatures::Probe();
-}
-
-
-bool CPU::SupportsCrankshaft() {
- return CpuFeatures::IsSupported(VFP3);
-}
-
-
void CPU::FlushICache(void* start, size_t size) {
// Nothing to do flushing no instructions.
if (size == 0) {
diff --git a/deps/v8/src/arm/debug-arm.cc b/deps/v8/src/arm/debug-arm.cc
index 12258ccad9..c3270f0bcd 100644
--- a/deps/v8/src/arm/debug-arm.cc
+++ b/deps/v8/src/arm/debug-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -35,7 +12,6 @@
namespace v8 {
namespace internal {
-#ifdef ENABLE_DEBUGGER_SUPPORT
bool BreakLocationIterator::IsDebugBreakAtReturn() {
return Debug::IsDebugBreakAtReturn(rinfo());
}
@@ -56,7 +32,7 @@ void BreakLocationIterator::SetDebugBreakAtReturn() {
patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0));
patcher.masm()->blx(v8::internal::ip);
patcher.Emit(
- debug_info_->GetIsolate()->debug()->debug_break_return()->entry());
+ debug_info_->GetIsolate()->builtins()->Return_DebugBreak()->entry());
patcher.masm()->bkpt(0);
}
@@ -97,7 +73,7 @@ void BreakLocationIterator::SetDebugBreakAtSlot() {
patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0));
patcher.masm()->blx(v8::internal::ip);
patcher.Emit(
- debug_info_->GetIsolate()->debug()->debug_break_slot()->entry());
+ debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry());
}
@@ -146,7 +122,7 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
__ mov(r0, Operand::Zero()); // no arguments
__ mov(r1, Operand(ExternalReference::debug_break(masm->isolate())));
- CEntryStub ceb(1);
+ CEntryStub ceb(masm->isolate(), 1);
__ CallStub(&ceb);
// Restore the register values from the expression stack.
@@ -179,6 +155,16 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
}
+void Debug::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
+ // Register state for CallICStub
+ // ----------- S t a t e -------------
+ // -- r1 : function
+ // -- r3 : slot in feedback array (smi)
+ // -----------------------------------
+ Generate_DebugBreakCallHelper(masm, r1.bit() | r3.bit(), 0);
+}
+
+
void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC load (from ic-arm.cc).
// ----------- S t a t e -------------
@@ -235,15 +221,6 @@ void Debug::GenerateCompareNilICDebugBreak(MacroAssembler* masm) {
}
-void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) {
- // Calling convention for IC call (from ic-arm.cc)
- // ----------- S t a t e -------------
- // -- r2 : name
- // -----------------------------------
- Generate_DebugBreakCallHelper(masm, r2.bit(), 0);
-}
-
-
void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
// In places other than IC call sites it is expected that r0 is TOS which
// is an object - this is not generally the case so this should be used with
@@ -261,17 +238,6 @@ void Debug::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
}
-void Debug::GenerateCallFunctionStubRecordDebugBreak(MacroAssembler* masm) {
- // Register state for CallFunctionStub (from code-stubs-arm.cc).
- // ----------- S t a t e -------------
- // -- r1 : function
- // -- r2 : feedback array
- // -- r3 : slot in feedback array
- // -----------------------------------
- Generate_DebugBreakCallHelper(masm, r1.bit() | r2.bit() | r3.bit(), 0);
-}
-
-
void Debug::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
// Calling convention for CallConstructStub (from code-stubs-arm.cc)
// ----------- S t a t e -------------
@@ -329,10 +295,6 @@ const bool Debug::kFrameDropperSupported = false;
#undef __
-
-
-#endif // ENABLE_DEBUGGER_SUPPORT
-
} } // namespace v8::internal
#endif // V8_TARGET_ARCH_ARM
diff --git a/deps/v8/src/arm/deoptimizer-arm.cc b/deps/v8/src/arm/deoptimizer-arm.cc
index ef3ea275cc..aa98c8b75f 100644
--- a/deps/v8/src/arm/deoptimizer-arm.cc
+++ b/deps/v8/src/arm/deoptimizer-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -54,7 +31,7 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
// Fail hard and early if we enter this code object again.
byte* pointer = code->FindCodeAgeSequence();
if (pointer != NULL) {
- pointer += kNoCodeAgeSequenceLength * Assembler::kInstrSize;
+ pointer += kNoCodeAgeSequenceLength;
} else {
pointer = code->instruction_start();
}
@@ -87,7 +64,8 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
// We need calls to have a predictable size in the unoptimized code, but
// this is optimized code, so we don't have to have a predictable size.
int call_size_in_bytes =
- MacroAssembler::CallSizeNotPredictableCodeSize(deopt_entry,
+ MacroAssembler::CallSizeNotPredictableCodeSize(isolate,
+ deopt_entry,
RelocInfo::NONE32);
int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize;
ASSERT(call_size_in_bytes % Assembler::kInstrSize == 0);
diff --git a/deps/v8/src/arm/disasm-arm.cc b/deps/v8/src/arm/disasm-arm.cc
index aa8ee22b73..0a5d5b0d39 100644
--- a/deps/v8/src/arm/disasm-arm.cc
+++ b/deps/v8/src/arm/disasm-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// A Disassembler object is used to disassemble a block of code instruction by
// instruction. The default implementation of the NameConverter object can be
@@ -1272,7 +1249,7 @@ void Decoder::DecodeTypeVFP(Instruction* instr) {
} else if ((instr->Opc2Value() == 0xA) && (instr->Opc3Value() == 0x3) &&
(instr->Bit(8) == 1)) {
// vcvt.f64.s32 Dd, Dd, #<fbits>
- int fraction_bits = 32 - ((instr->Bit(5) << 4) | instr->Bits(3, 0));
+ int fraction_bits = 32 - ((instr->Bits(3, 0) << 1) | instr->Bit(5));
Format(instr, "vcvt'cond.f64.s32 'Dd, 'Dd");
out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
", #%d", fraction_bits);
diff --git a/deps/v8/src/arm/frames-arm.cc b/deps/v8/src/arm/frames-arm.cc
index 780b48a8ef..605f9f4223 100644
--- a/deps/v8/src/arm/frames-arm.cc
+++ b/deps/v8/src/arm/frames-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/arm/frames-arm.h b/deps/v8/src/arm/frames-arm.h
index 29000ca3ab..6dd5186404 100644
--- a/deps/v8/src/arm/frames-arm.h
+++ b/deps/v8/src/arm/frames-arm.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM_FRAMES_ARM_H_
#define V8_ARM_FRAMES_ARM_H_
diff --git a/deps/v8/src/arm/full-codegen-arm.cc b/deps/v8/src/arm/full-codegen-arm.cc
index b5ec2d5fdf..c22caa4a81 100644
--- a/deps/v8/src/arm/full-codegen-arm.cc
+++ b/deps/v8/src/arm/full-codegen-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -118,14 +95,20 @@ static void EmitStackCheck(MacroAssembler* masm_,
Isolate* isolate = masm_->isolate();
Label ok;
ASSERT(scratch.is(sp) == (pointers == 0));
+ Heap::RootListIndex index;
if (pointers != 0) {
__ sub(scratch, sp, Operand(pointers * kPointerSize));
+ index = Heap::kRealStackLimitRootIndex;
+ } else {
+ index = Heap::kStackLimitRootIndex;
}
- __ LoadRoot(stack_limit_scratch, Heap::kStackLimitRootIndex);
+ __ LoadRoot(stack_limit_scratch, index);
__ cmp(scratch, Operand(stack_limit_scratch));
__ b(hs, &ok);
- PredictableCodeSizeScope predictable(masm_, 2 * Assembler::kInstrSize);
- __ Call(isolate->builtins()->StackCheck(), RelocInfo::CODE_TARGET);
+ Handle<Code> stack_check = isolate->builtins()->StackCheck();
+ PredictableCodeSizeScope predictable(masm_,
+ masm_->CallSize(stack_check, RelocInfo::CODE_TARGET));
+ __ Call(stack_check, RelocInfo::CODE_TARGET);
__ bind(&ok);
}
@@ -150,8 +133,6 @@ void FullCodeGenerator::Generate() {
handler_table_ =
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
- InitializeFeedbackVector();
-
profiling_counter_ = isolate()->factory()->NewCell(
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
SetFunctionPosition(function());
@@ -236,7 +217,7 @@ void FullCodeGenerator::Generate() {
__ Push(info->scope()->GetScopeInfo());
__ CallRuntime(Runtime::kHiddenNewGlobalContext, 2);
} else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
- FastNewContextStub stub(heap_slots);
+ FastNewContextStub stub(isolate(), heap_slots);
__ CallStub(&stub);
} else {
__ push(r1);
@@ -297,7 +278,7 @@ void FullCodeGenerator::Generate() {
} else {
type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
}
- ArgumentsAccessStub stub(type);
+ ArgumentsAccessStub stub(isolate(), type);
__ CallStub(&stub);
SetVar(arguments, r0, r1, r2);
@@ -1187,12 +1168,8 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Label non_proxy;
__ bind(&fixed_array);
- Handle<Object> feedback = Handle<Object>(
- Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
- isolate());
- StoreFeedbackVectorSlot(slot, feedback);
__ Move(r1, FeedbackVector());
- __ mov(r2, Operand(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker)));
+ __ mov(r2, Operand(TypeFeedbackInfo::MegamorphicSentinel(isolate())));
__ str(r2, FieldMemOperand(r1, FixedArray::OffsetOfElementAt(slot)));
__ mov(r1, Operand(Smi::FromInt(1))); // Smi indicates slow check
@@ -1351,7 +1328,9 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
!pretenure &&
scope()->is_function_scope() &&
info->num_literals() == 0) {
- FastNewClosureStub stub(info->strict_mode(), info->is_generator());
+ FastNewClosureStub stub(isolate(),
+ info->strict_mode(),
+ info->is_generator());
__ mov(r2, Operand(info));
__ CallStub(&stub);
} else {
@@ -1671,13 +1650,13 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
: ObjectLiteral::kNoFlags;
__ mov(r0, Operand(Smi::FromInt(flags)));
int properties_count = constant_properties->length() / 2;
- if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() ||
- flags != ObjectLiteral::kFastElements ||
+ if (expr->may_store_doubles() || expr->depth() > 1 ||
+ Serializer::enabled(isolate()) || flags != ObjectLiteral::kFastElements ||
properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
__ Push(r3, r2, r1, r0);
__ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4);
} else {
- FastCloneShallowObjectStub stub(properties_count);
+ FastCloneShallowObjectStub stub(isolate(), properties_count);
__ CallStub(&stub);
}
@@ -1816,13 +1795,14 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
if (has_fast_elements && constant_elements_values->map() ==
isolate()->heap()->fixed_cow_array_map()) {
FastCloneShallowArrayStub stub(
+ isolate(),
FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS,
allocation_site_mode,
length);
__ CallStub(&stub);
__ IncrementCounter(
isolate()->counters()->cow_arrays_created_stub(), 1, r1, r2);
- } else if (expr->depth() > 1 || Serializer::enabled() ||
+ } else if (expr->depth() > 1 || Serializer::enabled(isolate()) ||
length > FastCloneShallowArrayStub::kMaximumClonedLength) {
__ mov(r0, Operand(Smi::FromInt(flags)));
__ Push(r3, r2, r1, r0);
@@ -1837,7 +1817,8 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
mode = FastCloneShallowArrayStub::CLONE_ELEMENTS;
}
- FastCloneShallowArrayStub stub(mode, allocation_site_mode, length);
+ FastCloneShallowArrayStub stub(isolate(), mode, allocation_site_mode,
+ length);
__ CallStub(&stub);
}
@@ -1869,7 +1850,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
EMIT_REMEMBERED_SET, INLINE_SMI_CHECK);
} else {
__ mov(r3, Operand(Smi::FromInt(i)));
- StoreArrayLiteralElementStub stub;
+ StoreArrayLiteralElementStub stub(isolate());
__ CallStub(&stub);
}
@@ -1886,7 +1867,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
void FullCodeGenerator::VisitAssignment(Assignment* expr) {
- ASSERT(expr->target()->IsValidLeftHandSide());
+ ASSERT(expr->target()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ Assignment");
@@ -2114,7 +2095,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
CallIC(ic, TypeFeedbackId::None());
__ mov(r1, r0);
__ str(r1, MemOperand(sp, 2 * kPointerSize));
- CallFunctionStub stub(1, CALL_AS_METHOD);
+ CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
__ CallStub(&stub);
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2272,7 +2253,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
Label gc_required;
Label allocated;
- Handle<Map> map(isolate()->native_context()->generator_result_map());
+ Handle<Map> map(isolate()->native_context()->iterator_result_map());
__ Allocate(map->instance_size(), r0, r2, r3, &gc_required, TAG_OBJECT);
__ jmp(&allocated);
@@ -2343,8 +2324,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
__ bind(&stub_call);
- BinaryOpICStub stub(op, mode);
- CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
+ BinaryOpICStub stub(isolate(), op, mode);
+ CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done);
@@ -2419,16 +2400,16 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode) {
__ pop(r1);
- BinaryOpICStub stub(op, mode);
+ BinaryOpICStub stub(isolate(), op, mode);
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
- CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
+ CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
context()->Plug(r0);
}
void FullCodeGenerator::EmitAssignment(Expression* expr) {
- ASSERT(expr->IsValidLeftHandSide());
+ ASSERT(expr->IsValidReferenceExpression());
// Left-hand side can only be a property, a global or a (parameter or local)
// slot.
@@ -2628,14 +2609,15 @@ void FullCodeGenerator::CallIC(Handle<Code> code,
// Code common for calls using the IC.
-void FullCodeGenerator::EmitCallWithIC(Call* expr) {
+void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
- ZoneList<Expression*>* args = expr->arguments();
- int arg_count = args->length();
- CallFunctionFlags flags;
+ CallIC::CallType call_type = callee->IsVariableProxy()
+ ? CallIC::FUNCTION
+ : CallIC::METHOD;
+
// Get the target function.
- if (callee->IsVariableProxy()) {
+ if (call_type == CallIC::FUNCTION) {
{ StackValueContext context(this);
EmitVariableLoad(callee->AsVariableProxy());
PrepareForBailout(callee, NO_REGISTERS);
@@ -2643,7 +2625,6 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr) {
// Push undefined as receiver. This is patched in the method prologue if it
// is a sloppy mode method.
__ Push(isolate()->factory()->undefined_value());
- flags = NO_CALL_FUNCTION_FLAGS;
} else {
// Load the function from the receiver.
ASSERT(callee->IsProperty());
@@ -2654,40 +2635,19 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr) {
__ ldr(ip, MemOperand(sp, 0));
__ push(ip);
__ str(r0, MemOperand(sp, kPointerSize));
- flags = CALL_AS_METHOD;
}
- // Load the arguments.
- { PreservePositionScope scope(masm()->positions_recorder());
- for (int i = 0; i < arg_count; i++) {
- VisitForStackValue(args->at(i));
- }
- }
-
- // Record source position for debugger.
- SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, flags);
- __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
- __ CallStub(&stub);
-
- RecordJSReturnSite(expr);
-
- // Restore context register.
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-
- context()->DropAndPlug(1, r0);
+ EmitCall(expr, call_type);
}
// Code common for calls using the IC.
-void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
- Expression* key) {
+void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
+ Expression* key) {
// Load the key.
VisitForAccumulatorValue(key);
Expression* callee = expr->expression();
- ZoneList<Expression*>* args = expr->arguments();
- int arg_count = args->length();
// Load the function from the receiver.
ASSERT(callee->IsProperty());
@@ -2700,28 +2660,12 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
__ push(ip);
__ str(r0, MemOperand(sp, kPointerSize));
- { PreservePositionScope scope(masm()->positions_recorder());
- for (int i = 0; i < arg_count; i++) {
- VisitForStackValue(args->at(i));
- }
- }
-
- // Record source position for debugger.
- SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, CALL_AS_METHOD);
- __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
- __ CallStub(&stub);
-
- RecordJSReturnSite(expr);
- // Restore context register.
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-
- context()->DropAndPlug(1, r0);
+ EmitCall(expr, CallIC::METHOD);
}
-void FullCodeGenerator::EmitCallWithStub(Call* expr) {
- // Code common for calls using the call stub.
+void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) {
+ // Load the arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope scope(masm()->positions_recorder());
@@ -2729,19 +2673,17 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr) {
VisitForStackValue(args->at(i));
}
}
- // Record source position for debugger.
- SetSourcePosition(expr->position());
- Handle<Object> uninitialized =
- TypeFeedbackInfo::UninitializedSentinel(isolate());
- StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
- __ Move(r2, FeedbackVector());
+ // Record source position of the IC call.
+ SetSourcePosition(expr->position());
+ Handle<Code> ic = CallIC::initialize_stub(
+ isolate(), arg_count, call_type);
__ mov(r3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
-
- // Record call targets in unoptimized code.
- CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
- __ CallStub(&stub);
+ // Don't assign a type feedback id to the IC, since type feedback is provided
+ // by the vector above.
+ CallIC(ic);
+
RecordJSReturnSite(expr);
// Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2816,7 +2758,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// Record source position for debugger.
SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
+ CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
RecordJSReturnSite(expr);
@@ -2824,7 +2766,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
context()->DropAndPlug(1, r0);
} else if (call_type == Call::GLOBAL_CALL) {
- EmitCallWithIC(expr);
+ EmitCallWithLoadIC(expr);
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
// Call to a lookup slot (dynamically introduced variable).
@@ -2864,16 +2806,16 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// The receiver is either the global receiver or an object found
// by LoadContextSlot.
- EmitCallWithStub(expr);
+ EmitCall(expr);
} else if (call_type == Call::PROPERTY_CALL) {
Property* property = callee->AsProperty();
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
if (property->key()->IsPropertyName()) {
- EmitCallWithIC(expr);
+ EmitCallWithLoadIC(expr);
} else {
- EmitKeyedCallWithIC(expr, property->key());
+ EmitKeyedCallWithLoadIC(expr, property->key());
}
} else {
ASSERT(call_type == Call::OTHER_CALL);
@@ -2884,7 +2826,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
__ push(r1);
// Emit function call.
- EmitCallWithStub(expr);
+ EmitCall(expr);
}
#ifdef DEBUG
@@ -2921,12 +2863,8 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
__ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
// Record call targets in unoptimized code.
- Handle<Object> uninitialized =
- TypeFeedbackInfo::UninitializedSentinel(isolate());
- StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
if (FLAG_pretenuring_call_new) {
- StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(),
- isolate()->factory()->NewAllocationSite());
+ EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
ASSERT(expr->AllocationSiteFeedbackSlot() ==
expr->CallNewFeedbackSlot() + 1);
}
@@ -2934,8 +2872,8 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
__ Move(r2, FeedbackVector());
__ mov(r3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
- CallConstructStub stub(RECORD_CALL_TARGET);
- __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
+ CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
+ __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
context()->Plug(r0);
}
@@ -3305,7 +3243,7 @@ void FullCodeGenerator::EmitArguments(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(0));
__ mov(r1, r0);
__ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
- ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
+ ArgumentsAccessStub stub(isolate(), ArgumentsAccessStub::READ_ELEMENT);
__ CallStub(&stub);
context()->Plug(r0);
}
@@ -3391,31 +3329,9 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
}
-void FullCodeGenerator::EmitLog(CallRuntime* expr) {
- // Conditionally generate a log call.
- // Args:
- // 0 (literal string): The type of logging (corresponds to the flags).
- // This is used to determine whether or not to generate the log call.
- // 1 (string): Format string. Access the string at argument index 2
- // with '%2s' (see Logger::LogRuntime for all the formats).
- // 2 (array): Arguments to the format string.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT_EQ(args->length(), 3);
- if (CodeGenerator::ShouldGenerateLog(isolate(), args->at(0))) {
- VisitForStackValue(args->at(1));
- VisitForStackValue(args->at(2));
- __ CallRuntime(Runtime::kHiddenLog, 2);
- }
-
- // Finally, we're expected to leave a value on the top of the stack.
- __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
- context()->Plug(r0);
-}
-
-
void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
// Load the arguments on the stack and call the stub.
- SubStringStub stub;
+ SubStringStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 3);
VisitForStackValue(args->at(0));
@@ -3428,7 +3344,7 @@ void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) {
// Load the arguments on the stack and call the stub.
- RegExpExecStub stub;
+ RegExpExecStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 4);
VisitForStackValue(args->at(0));
@@ -3578,7 +3494,7 @@ void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
ASSERT(args->length() == 2);
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
- MathPowStub stub(MathPowStub::ON_STACK);
+ MathPowStub stub(isolate(), MathPowStub::ON_STACK);
__ CallStub(&stub);
context()->Plug(r0);
}
@@ -3618,7 +3534,7 @@ void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
// Load the argument into r0 and call the stub.
VisitForAccumulatorValue(args->at(0));
- NumberToStringStub stub;
+ NumberToStringStub stub(isolate());
__ CallStub(&stub);
context()->Plug(r0);
}
@@ -3741,7 +3657,7 @@ void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(1));
__ pop(r1);
- StringAddStub stub(STRING_ADD_CHECK_BOTH, NOT_TENURED);
+ StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED);
__ CallStub(&stub);
context()->Plug(r0);
}
@@ -3753,32 +3669,12 @@ void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
- StringCompareStub stub;
+ StringCompareStub stub(isolate());
__ CallStub(&stub);
context()->Plug(r0);
}
-void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_log, 1);
- context()->Plug(r0);
-}
-
-
-void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_sqrt, 1);
- context()->Plug(r0);
-}
-
-
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() >= 2);
@@ -3812,7 +3708,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
- RegExpConstructResultStub stub;
+ RegExpConstructResultStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 3);
VisitForStackValue(args->at(0));
@@ -4178,7 +4074,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
// Record source position of the IC call.
SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
+ CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
@@ -4310,7 +4206,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
- ASSERT(expr->expression()->IsValidLeftHandSide());
+ ASSERT(expr->expression()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ CountOperation");
SetSourcePosition(expr->position());
@@ -4396,7 +4292,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ jmp(&stub_call);
__ bind(&slow);
}
- ToNumberStub convert_stub;
+ ToNumberStub convert_stub(isolate());
__ CallStub(&convert_stub);
// Save result for postfix expressions.
@@ -4427,8 +4323,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
// Record position before stub call.
SetSourcePosition(expr->position());
- BinaryOpICStub stub(Token::ADD, NO_OVERWRITE);
- CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId());
+ BinaryOpICStub stub(isolate(), Token::ADD, NO_OVERWRITE);
+ CallIC(stub.GetCode(), expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
@@ -4539,13 +4435,14 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
}
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
- if (check->Equals(isolate()->heap()->number_string())) {
+ Factory* factory = isolate()->factory();
+ if (String::Equals(check, factory->number_string())) {
__ JumpIfSmi(r0, if_true);
__ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
__ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
__ cmp(r0, ip);
Split(eq, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->string_string())) {
+ } else if (String::Equals(check, factory->string_string())) {
__ JumpIfSmi(r0, if_false);
// Check for undetectable objects => false.
__ CompareObjectType(r0, r0, r1, FIRST_NONSTRING_TYPE);
@@ -4553,20 +4450,20 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset));
__ tst(r1, Operand(1 << Map::kIsUndetectable));
Split(eq, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->symbol_string())) {
+ } else if (String::Equals(check, factory->symbol_string())) {
__ JumpIfSmi(r0, if_false);
__ CompareObjectType(r0, r0, r1, SYMBOL_TYPE);
Split(eq, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->boolean_string())) {
+ } else if (String::Equals(check, factory->boolean_string())) {
__ CompareRoot(r0, Heap::kTrueValueRootIndex);
__ b(eq, if_true);
__ CompareRoot(r0, Heap::kFalseValueRootIndex);
Split(eq, if_true, if_false, fall_through);
} else if (FLAG_harmony_typeof &&
- check->Equals(isolate()->heap()->null_string())) {
+ String::Equals(check, factory->null_string())) {
__ CompareRoot(r0, Heap::kNullValueRootIndex);
Split(eq, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->undefined_string())) {
+ } else if (String::Equals(check, factory->undefined_string())) {
__ CompareRoot(r0, Heap::kUndefinedValueRootIndex);
__ b(eq, if_true);
__ JumpIfSmi(r0, if_false);
@@ -4576,14 +4473,14 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ tst(r1, Operand(1 << Map::kIsUndetectable));
Split(ne, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->function_string())) {
+ } else if (String::Equals(check, factory->function_string())) {
__ JumpIfSmi(r0, if_false);
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
__ CompareObjectType(r0, r0, r1, JS_FUNCTION_TYPE);
__ b(eq, if_true);
__ cmp(r1, Operand(JS_FUNCTION_PROXY_TYPE));
Split(eq, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->object_string())) {
+ } else if (String::Equals(check, factory->object_string())) {
__ JumpIfSmi(r0, if_false);
if (!FLAG_harmony_typeof) {
__ CompareRoot(r0, Heap::kNullValueRootIndex);
@@ -4636,7 +4533,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
case Token::INSTANCEOF: {
VisitForStackValue(expr->right());
- InstanceofStub stub(InstanceofStub::kNoFlags);
+ InstanceofStub stub(isolate(), InstanceofStub::kNoFlags);
__ CallStub(&stub);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
// The stub returns 0 for true.
@@ -4780,7 +4677,8 @@ void FullCodeGenerator::EnterFinallyBlock() {
ExternalReference has_pending_message =
ExternalReference::address_of_has_pending_message(isolate());
__ mov(ip, Operand(has_pending_message));
- __ ldr(r1, MemOperand(ip));
+ STATIC_ASSERT(sizeof(bool) == 1); // NOLINT(runtime/sizeof)
+ __ ldrb(r1, MemOperand(ip));
__ SmiTag(r1);
__ push(r1);
@@ -4806,7 +4704,8 @@ void FullCodeGenerator::ExitFinallyBlock() {
ExternalReference has_pending_message =
ExternalReference::address_of_has_pending_message(isolate());
__ mov(ip, Operand(has_pending_message));
- __ str(r1, MemOperand(ip));
+ STATIC_ASSERT(sizeof(bool) == 1); // NOLINT(runtime/sizeof)
+ __ strb(r1, MemOperand(ip));
__ pop(r1);
ExternalReference pending_message_obj =
diff --git a/deps/v8/src/arm/ic-arm.cc b/deps/v8/src/arm/ic-arm.cc
index 3d57105afe..4626e37516 100644
--- a/deps/v8/src/arm/ic-arm.cc
+++ b/deps/v8/src/arm/ic-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/arm/lithium-arm.cc b/deps/v8/src/arm/lithium-arm.cc
index 55705b8073..0c10a65c21 100644
--- a/deps/v8/src/arm/lithium-arm.cc
+++ b/deps/v8/src/arm/lithium-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -623,6 +600,8 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
!hinstr->HasObservableSideEffects();
if (needs_environment && !instr->HasEnvironment()) {
instr = AssignEnvironment(instr);
+ // We can't really figure out if the environment is needed or not.
+ instr->environment()->set_has_been_used();
}
return instr;
@@ -871,7 +850,8 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
// the it was just a plain use), so it is free to move the split child into
// the same register that is used for the use-at-start.
// See https://code.google.com/p/chromium/issues/detail?id=201590
- if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) {
+ if (!(instr->ClobbersRegisters() &&
+ instr->ClobbersDoubleRegisters(isolate()))) {
int fixed = 0;
int used_at_start = 0;
for (UseIterator it(instr); !it.Done(); it.Advance()) {
@@ -931,18 +911,20 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
if (goto_instr != NULL) return goto_instr;
HValue* value = instr->value();
- LBranch* result = new(zone()) LBranch(UseRegister(value));
- // Tagged values that are not known smis or booleans require a
- // deoptimization environment. If the instruction is generic no
- // environment is needed since all cases are handled.
- Representation rep = value->representation();
+ Representation r = value->representation();
HType type = value->type();
ToBooleanStub::Types expected = instr->expected_input_types();
- if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() &&
- !expected.IsGeneric()) {
- return AssignEnvironment(result);
+ if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic();
+
+ bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() ||
+ type.IsJSArray() || type.IsHeapNumber() || type.IsString();
+ LInstruction* branch = new(zone()) LBranch(UseRegister(value));
+ if (!easy_case &&
+ ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) ||
+ !expected.IsGeneric())) {
+ branch = AssignEnvironment(branch);
}
- return result;
+ return branch;
}
@@ -1138,8 +1120,11 @@ LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
? NULL
: UseFixed(instr->context(), cp);
LOperand* input = UseRegister(instr->value());
- LMathAbs* result = new(zone()) LMathAbs(context, input);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ LInstruction* result =
+ DefineAsRegister(new(zone()) LMathAbs(context, input));
+ if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result);
+ if (!r.IsDouble()) result = AssignEnvironment(result);
+ return result;
}
@@ -1284,15 +1269,25 @@ LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) {
}
-LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
+LInstruction* LChunkBuilder::DoDivI(HDiv* instr) {
ASSERT(instr->representation().IsSmiOrInteger32());
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* dividend = UseRegister(instr->left());
LOperand* divisor = UseRegister(instr->right());
LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4);
- LDivI* div = new(zone()) LDivI(dividend, divisor, temp);
- return AssignEnvironment(DefineAsRegister(div));
+ LInstruction* result =
+ DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp));
+ if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+ instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+ (instr->CheckFlag(HValue::kCanOverflow) &&
+ (!CpuFeatures::IsSupported(SUDIV) ||
+ !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) ||
+ (!instr->IsMathFloorOfDiv() &&
+ !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -1346,13 +1341,25 @@ LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
}
+LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
+ ASSERT(instr->representation().IsSmiOrInteger32());
+ ASSERT(instr->left()->representation().Equals(instr->representation()));
+ ASSERT(instr->right()->representation().Equals(instr->representation()));
+ LOperand* dividend = UseRegister(instr->left());
+ LOperand* divisor = UseRegister(instr->right());
+ LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4);
+ LFlooringDivI* div = new(zone()) LFlooringDivI(dividend, divisor, temp);
+ return AssignEnvironment(DefineAsRegister(div));
+}
+
+
LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
if (instr->RightIsPowerOf2()) {
return DoFlooringDivByPowerOf2I(instr);
} else if (instr->right()->IsConstant()) {
return DoFlooringDivByConstI(instr);
} else {
- return DoDivI(instr);
+ return DoFlooringDivI(instr);
}
}
@@ -1647,6 +1654,8 @@ LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
LInstruction* LChunkBuilder::DoCompareNumericAndBranch(
HCompareNumericAndBranch* instr) {
+ LInstruction* goto_instr = CheckElideControlInstruction(instr);
+ if (goto_instr != NULL) return goto_instr;
Representation r = instr->representation();
if (r.IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().Equals(r));
@@ -1801,9 +1810,16 @@ LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
- LOperand* value = UseRegisterOrConstantAtStart(instr->index());
- LOperand* length = UseRegister(instr->length());
- return AssignEnvironment(new(zone()) LBoundsCheck(value, length));
+ if (!FLAG_debug_code && instr->skip_check()) return NULL;
+ LOperand* index = UseRegisterOrConstantAtStart(instr->index());
+ LOperand* length = !index->IsConstantOperand()
+ ? UseRegisterOrConstantAtStart(instr->length())
+ : UseRegisterAtStart(instr->length());
+ LInstruction* result = new(zone()) LBoundsCheck(index, length);
+ if (!FLAG_debug_code || !instr->skip_check()) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -1837,20 +1853,21 @@ LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
LInstruction* LChunkBuilder::DoChange(HChange* instr) {
Representation from = instr->from();
Representation to = instr->to();
+ HValue* val = instr->value();
if (from.IsSmi()) {
if (to.IsTagged()) {
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
return DefineSameAsFirst(new(zone()) LDummyUse(value));
}
from = Representation::Tagged();
}
if (from.IsTagged()) {
if (to.IsDouble()) {
- LOperand* value = UseRegister(instr->value());
- LNumberUntagD* res = new(zone()) LNumberUntagD(value);
- return AssignEnvironment(DefineAsRegister(res));
+ LOperand* value = UseRegister(val);
+ LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value));
+ if (!val->representation().IsSmi()) result = AssignEnvironment(result);
+ return result;
} else if (to.IsSmi()) {
- HValue* val = instr->value();
LOperand* value = UseRegister(val);
if (val->type().IsSmi()) {
return DefineSameAsFirst(new(zone()) LDummyUse(value));
@@ -1858,66 +1875,59 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
} else {
ASSERT(to.IsInteger32());
- LOperand* value = NULL;
- LInstruction* res = NULL;
- HValue* val = instr->value();
if (val->type().IsSmi() || val->representation().IsSmi()) {
- value = UseRegisterAtStart(val);
- res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
+ LOperand* value = UseRegisterAtStart(val);
+ return DefineAsRegister(new(zone()) LSmiUntag(value, false));
} else {
- value = UseRegister(val);
+ LOperand* value = UseRegister(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = FixedTemp(d11);
- res = DefineSameAsFirst(new(zone()) LTaggedToI(value,
- temp1,
- temp2));
- res = AssignEnvironment(res);
+ LInstruction* result =
+ DefineSameAsFirst(new(zone()) LTaggedToI(value, temp1, temp2));
+ if (!val->representation().IsSmi()) result = AssignEnvironment(result);
+ return result;
}
- return res;
}
} else if (from.IsDouble()) {
if (to.IsTagged()) {
info()->MarkAsDeferredCalling();
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister();
-
- // Make sure that the temp and result_temp registers are
- // different.
LUnallocated* result_temp = TempRegister();
LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2);
- Define(result, result_temp);
- return AssignPointerMap(result);
+ return AssignPointerMap(Define(result, result_temp));
} else if (to.IsSmi()) {
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
return AssignEnvironment(
DefineAsRegister(new(zone()) LDoubleToSmi(value)));
} else {
ASSERT(to.IsInteger32());
- LOperand* value = UseRegister(instr->value());
- LDoubleToI* res = new(zone()) LDoubleToI(value);
- return AssignEnvironment(DefineAsRegister(res));
+ LOperand* value = UseRegister(val);
+ LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value));
+ if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result);
+ return result;
}
} else if (from.IsInteger32()) {
info()->MarkAsDeferredCalling();
if (to.IsTagged()) {
- HValue* val = instr->value();
- LOperand* value = UseRegisterAtStart(val);
if (!instr->CheckFlag(HValue::kCanOverflow)) {
+ LOperand* value = UseRegisterAtStart(val);
return DefineAsRegister(new(zone()) LSmiTag(value));
} else if (val->CheckFlag(HInstruction::kUint32)) {
+ LOperand* value = UseRegisterAtStart(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister();
LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ return AssignPointerMap(DefineAsRegister(result));
} else {
+ LOperand* value = UseRegisterAtStart(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister();
LNumberTagI* result = new(zone()) LNumberTagI(value, temp1, temp2);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ return AssignPointerMap(DefineAsRegister(result));
}
} else if (to.IsSmi()) {
- HValue* val = instr->value();
LOperand* value = UseRegister(val);
LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
if (instr->CheckFlag(HValue::kCanOverflow)) {
@@ -1926,12 +1936,10 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
return result;
} else {
ASSERT(to.IsDouble());
- if (instr->value()->CheckFlag(HInstruction::kUint32)) {
- return DefineAsRegister(
- new(zone()) LUint32ToDouble(UseRegister(instr->value())));
+ if (val->CheckFlag(HInstruction::kUint32)) {
+ return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val)));
} else {
- return DefineAsRegister(
- new(zone()) LInteger32ToDouble(Use(instr->value())));
+ return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val)));
}
}
}
@@ -1942,7 +1950,9 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
LOperand* value = UseRegisterAtStart(instr->value());
- return AssignEnvironment(new(zone()) LCheckNonSmi(value));
+ LInstruction* result = new(zone()) LCheckNonSmi(value);
+ if (!instr->value()->IsHeapObject()) result = AssignEnvironment(result);
+ return result;
}
@@ -1966,15 +1976,12 @@ LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
- LOperand* value = NULL;
- if (!instr->CanOmitMapChecks()) {
- value = UseRegisterAtStart(instr->value());
- if (instr->has_migration_target()) info()->MarkAsDeferredCalling();
- }
- LCheckMaps* result = new(zone()) LCheckMaps(value);
- if (!instr->CanOmitMapChecks()) {
- AssignEnvironment(result);
- if (instr->has_migration_target()) return AssignPointerMap(result);
+ if (instr->IsStabilityCheck()) return new(zone()) LCheckMaps;
+ LOperand* value = UseRegisterAtStart(instr->value());
+ LInstruction* result = AssignEnvironment(new(zone()) LCheckMaps(value));
+ if (instr->HasMigrationTarget()) {
+ info()->MarkAsDeferredCalling();
+ result = AssignPointerMap(result);
}
return result;
}
@@ -2072,7 +2079,10 @@ LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
LOperand* context = UseRegisterAtStart(instr->value());
LInstruction* result =
DefineAsRegister(new(zone()) LLoadContextSlot(context));
- return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
+ if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -2087,7 +2097,10 @@ LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
value = UseRegister(instr->value());
}
LInstruction* result = new(zone()) LStoreContextSlot(context, value);
- return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
+ if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -2122,7 +2135,7 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
ASSERT(instr->key()->representation().IsSmiOrInteger32());
ElementsKind elements_kind = instr->elements_kind();
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
- LLoadKeyed* result = NULL;
+ LInstruction* result = NULL;
if (!instr->is_typed_elements()) {
LOperand* obj = NULL;
@@ -2132,24 +2145,28 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
ASSERT(instr->representation().IsSmiOrTagged());
obj = UseRegisterAtStart(instr->elements());
}
- result = new(zone()) LLoadKeyed(obj, key);
+ result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key));
} else {
ASSERT(
(instr->representation().IsInteger32() &&
- !IsDoubleOrFloatElementsKind(instr->elements_kind())) ||
+ !IsDoubleOrFloatElementsKind(elements_kind)) ||
(instr->representation().IsDouble() &&
- IsDoubleOrFloatElementsKind(instr->elements_kind())));
+ IsDoubleOrFloatElementsKind(elements_kind)));
LOperand* backing_store = UseRegister(instr->elements());
- result = new(zone()) LLoadKeyed(backing_store, key);
+ result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key));
}
- DefineAsRegister(result);
- // An unsigned int array load might overflow and cause a deopt, make sure it
- // has an environment.
- bool can_deoptimize = instr->RequiresHoleCheck() ||
- elements_kind == EXTERNAL_UINT32_ELEMENTS ||
- elements_kind == UINT32_ELEMENTS;
- return can_deoptimize ? AssignEnvironment(result) : result;
+ if ((instr->is_external() || instr->is_fixed_typed_array()) ?
+ // see LCodeGen::DoLoadKeyedExternalArray
+ ((elements_kind == EXTERNAL_UINT32_ELEMENTS ||
+ elements_kind == UINT32_ELEMENTS) &&
+ !instr->CheckFlag(HInstruction::kUint32)) :
+ // see LCodeGen::DoLoadKeyedFixedDoubleArray and
+ // LCodeGen::DoLoadKeyedFixedArray
+ instr->RequiresHoleCheck()) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -2225,17 +2242,18 @@ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- LOperand* object = UseRegister(instr->object());
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
+ LOperand* object = UseRegister(instr->object());
LOperand* new_map_reg = TempRegister();
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, NULL, new_map_reg);
return result;
} else {
+ LOperand* object = UseFixed(instr->object(), r0);
LOperand* context = UseFixed(instr->context(), cp);
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, context, NULL);
- return AssignPointerMap(result);
+ return MarkAsCall(result, instr);
}
}
@@ -2279,11 +2297,11 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
// We need a temporary register for write barrier of the map field.
LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;
- LStoreNamedField* result = new(zone()) LStoreNamedField(obj, val, temp);
- if (instr->field_representation().IsHeapObject()) {
- if (!instr->value()->type().IsHeapObject()) {
- return AssignEnvironment(result);
- }
+ LInstruction* result = new(zone()) LStoreNamedField(obj, val, temp);
+ if (!instr->access().IsExternalMemory() &&
+ instr->field_representation().IsHeapObject() &&
+ !instr->value()->type().IsHeapObject()) {
+ result = AssignEnvironment(result);
}
return result;
}
@@ -2315,7 +2333,7 @@ LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
LOperand* context = UseAny(instr->context());
LStringCharCodeAt* result =
new(zone()) LStringCharCodeAt(context, string, index);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ return AssignPointerMap(DefineAsRegister(result));
}
@@ -2371,7 +2389,7 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
} else {
ASSERT(info()->IsStub());
CodeStubInterfaceDescriptor* descriptor =
- info()->code_stub()->GetInterfaceDescriptor(info()->isolate());
+ info()->code_stub()->GetInterfaceDescriptor();
int index = static_cast<int>(instr->index());
Register reg = descriptor->GetParameterRegister(index);
return DefineFixed(result, reg);
@@ -2478,6 +2496,7 @@ LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
HEnvironment* outer = current_block_->last_environment();
+ outer->set_ast_id(instr->ReturnId());
HConstant* undefined = graph()->GetConstantUndefined();
HEnvironment* inner = outer->CopyForInlining(instr->closure(),
instr->arguments_count(),
@@ -2538,7 +2557,9 @@ LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
LOperand* object = UseRegister(instr->object());
LOperand* index = UseRegister(instr->index());
- return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index));
+ LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index);
+ LInstruction* result = DefineSameAsFirst(load);
+ return AssignPointerMap(result);
}
} } // namespace v8::internal
diff --git a/deps/v8/src/arm/lithium-arm.h b/deps/v8/src/arm/lithium-arm.h
index 34eb510177..1a90eb638b 100644
--- a/deps/v8/src/arm/lithium-arm.h
+++ b/deps/v8/src/arm/lithium-arm.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM_LITHIUM_ARM_H_
#define V8_ARM_LITHIUM_ARM_H_
@@ -97,6 +74,7 @@ class LCodeGen;
V(DummyUse) \
V(FlooringDivByConstI) \
V(FlooringDivByPowerOf2I) \
+ V(FlooringDivI) \
V(ForInCacheArray) \
V(ForInPrepareMap) \
V(FunctionLiteral) \
@@ -261,7 +239,9 @@ class LInstruction : public ZoneObject {
// Interface to the register allocator and iterators.
bool ClobbersTemps() const { return IsCall(); }
bool ClobbersRegisters() const { return IsCall(); }
- virtual bool ClobbersDoubleRegisters() const { return IsCall(); }
+ virtual bool ClobbersDoubleRegisters(Isolate* isolate) const {
+ return IsCall();
+ }
// Interface to the register allocator and iterators.
bool IsMarkedAsCall() const { return IsCall(); }
@@ -713,14 +693,14 @@ class LDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 0> {
class LDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
public:
- LDivI(LOperand* left, LOperand* right, LOperand* temp) {
- inputs_[0] = left;
- inputs_[1] = right;
+ LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
+ inputs_[0] = dividend;
+ inputs_[1] = divisor;
temps_[0] = temp;
}
- LOperand* left() { return inputs_[0]; }
- LOperand* right() { return inputs_[1]; }
+ LOperand* dividend() { return inputs_[0]; }
+ LOperand* divisor() { return inputs_[1]; }
LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
@@ -767,6 +747,23 @@ class LFlooringDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 2> {
};
+class LFlooringDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
+ public:
+ LFlooringDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
+ inputs_[0] = dividend;
+ inputs_[1] = divisor;
+ temps_[0] = temp;
+ }
+
+ LOperand* dividend() { return inputs_[0]; }
+ LOperand* divisor() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i")
+ DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+};
+
+
class LMulI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public:
LMulI(LOperand* left, LOperand* right) {
@@ -1968,7 +1965,7 @@ class LCallRuntime V8_FINAL : public LTemplateInstruction<1, 1, 0> {
DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
- virtual bool ClobbersDoubleRegisters() const V8_OVERRIDE {
+ virtual bool ClobbersDoubleRegisters(Isolate* isolate) const V8_OVERRIDE {
return save_doubles() == kDontSaveFPRegs;
}
@@ -2164,7 +2161,6 @@ class LStoreNamedField V8_FINAL : public LTemplateInstruction<0, 2, 1> {
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
- Handle<Map> transition() const { return hydrogen()->transition_map(); }
Representation representation() const {
return hydrogen()->field_representation();
}
@@ -2379,7 +2375,7 @@ class LCheckInstanceType V8_FINAL : public LTemplateInstruction<0, 1, 0> {
class LCheckMaps V8_FINAL : public LTemplateInstruction<0, 1, 0> {
public:
- explicit LCheckMaps(LOperand* value) {
+ explicit LCheckMaps(LOperand* value = NULL) {
inputs_[0] = value;
}
@@ -2696,6 +2692,8 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
next_block_(NULL),
allocator_(allocator) { }
+ Isolate* isolate() const { return graph_->isolate(); }
+
// Build the sequence for the graph.
LPlatformChunk* Build();
@@ -2722,12 +2720,13 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
LInstruction* DoMathClz32(HUnaryMathOperation* instr);
LInstruction* DoDivByPowerOf2I(HDiv* instr);
LInstruction* DoDivByConstI(HDiv* instr);
- LInstruction* DoDivI(HBinaryOperation* instr);
+ LInstruction* DoDivI(HDiv* instr);
LInstruction* DoModByPowerOf2I(HMod* instr);
LInstruction* DoModByConstI(HMod* instr);
LInstruction* DoModI(HMod* instr);
LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr);
LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr);
+ LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr);
private:
enum Status {
diff --git a/deps/v8/src/arm/lithium-codegen-arm.cc b/deps/v8/src/arm/lithium-codegen-arm.cc
index 7152ba21cc..5a01d3bc84 100644
--- a/deps/v8/src/arm/lithium-codegen-arm.cc
+++ b/deps/v8/src/arm/lithium-codegen-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -86,13 +63,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
PopulateDeoptimizationData(code);
- info()->CommitDependencies(code);
-}
-
-
-void LCodeGen::Abort(BailoutReason reason) {
- info()->set_bailout_reason(reason);
- status_ = ABORTED;
}
@@ -207,7 +177,7 @@ bool LCodeGen::GeneratePrologue() {
Comment(";;; Allocate local context");
// Argument to NewContext is the function, which is in r1.
if (heap_slots <= FastNewContextStub::kMaximumSlots) {
- FastNewContextStub stub(heap_slots);
+ FastNewContextStub stub(isolate(), heap_slots);
__ CallStub(&stub);
} else {
__ push(r1);
@@ -714,6 +684,16 @@ void LCodeGen::AddToTranslation(LEnvironment* environment,
}
+int LCodeGen::CallCodeSize(Handle<Code> code, RelocInfo::Mode mode) {
+ int size = masm()->CallSize(code, mode);
+ if (code->kind() == Code::BINARY_OP_IC ||
+ code->kind() == Code::COMPARE_IC) {
+ size += Assembler::kInstrSize; // extra nop() added in CallCodeGeneric.
+ }
+ return size;
+}
+
+
void LCodeGen::CallCode(Handle<Code> code,
RelocInfo::Mode mode,
LInstruction* instr,
@@ -783,6 +763,7 @@ void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment,
Safepoint::DeoptMode mode) {
+ environment->set_has_been_used();
if (!environment->HasBeenRegistered()) {
// Physical stack frame layout:
// -x ............. -4 0 ..................................... y
@@ -906,7 +887,7 @@ void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
int length = deoptimizations_.length();
if (length == 0) return;
Handle<DeoptimizationInputData> data =
- factory()->NewDeoptimizationInputData(length, TENURED);
+ DeoptimizationInputData::New(isolate(), length, TENURED);
Handle<ByteArray> translations =
translations_.CreateByteArray(isolate()->factory());
@@ -1095,18 +1076,18 @@ void LCodeGen::DoCallStub(LCallStub* instr) {
ASSERT(ToRegister(instr->result()).is(r0));
switch (instr->hydrogen()->major_key()) {
case CodeStub::RegExpExec: {
- RegExpExecStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ RegExpExecStub stub(isolate());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
case CodeStub::SubString: {
- SubStringStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ SubStringStub stub(isolate());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
case CodeStub::StringCompare: {
- StringCompareStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ StringCompareStub stub(isolate());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
default:
@@ -1293,7 +1274,7 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
Register dividend = ToRegister(instr->dividend());
int32_t divisor = instr->divisor();
Register result = ToRegister(instr->result());
- ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor))));
+ ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor)));
ASSERT(!result.is(dividend));
// Check for (0 / -x) that will produce negative zero.
@@ -1363,15 +1344,16 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
}
+// TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI.
void LCodeGen::DoDivI(LDivI* instr) {
HBinaryOperation* hdiv = instr->hydrogen();
- Register left = ToRegister(instr->left());
- Register right = ToRegister(instr->right());
+ Register dividend = ToRegister(instr->dividend());
+ Register divisor = ToRegister(instr->divisor());
Register result = ToRegister(instr->result());
// Check for x / 0.
if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
- __ cmp(right, Operand::Zero());
+ __ cmp(divisor, Operand::Zero());
DeoptimizeIf(eq, instr->environment());
}
@@ -1380,10 +1362,10 @@ void LCodeGen::DoDivI(LDivI* instr) {
Label positive;
if (!instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
// Do the test only if it hadn't be done above.
- __ cmp(right, Operand::Zero());
+ __ cmp(divisor, Operand::Zero());
}
__ b(pl, &positive);
- __ cmp(left, Operand::Zero());
+ __ cmp(dividend, Operand::Zero());
DeoptimizeIf(eq, instr->environment());
__ bind(&positive);
}
@@ -1394,39 +1376,30 @@ void LCodeGen::DoDivI(LDivI* instr) {
!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
// We don't need to check for overflow when truncating with sdiv
// support because, on ARM, sdiv kMinInt, -1 -> kMinInt.
- __ cmp(left, Operand(kMinInt));
- __ cmp(right, Operand(-1), eq);
+ __ cmp(dividend, Operand(kMinInt));
+ __ cmp(divisor, Operand(-1), eq);
DeoptimizeIf(eq, instr->environment());
}
if (CpuFeatures::IsSupported(SUDIV)) {
CpuFeatureScope scope(masm(), SUDIV);
- __ sdiv(result, left, right);
+ __ sdiv(result, dividend, divisor);
} else {
DoubleRegister vleft = ToDoubleRegister(instr->temp());
DoubleRegister vright = double_scratch0();
- __ vmov(double_scratch0().low(), left);
+ __ vmov(double_scratch0().low(), dividend);
__ vcvt_f64_s32(vleft, double_scratch0().low());
- __ vmov(double_scratch0().low(), right);
+ __ vmov(double_scratch0().low(), divisor);
__ vcvt_f64_s32(vright, double_scratch0().low());
__ vdiv(vleft, vleft, vright); // vleft now contains the result.
__ vcvt_s32_f64(double_scratch0().low(), vleft);
__ vmov(result, double_scratch0().low());
}
- if (hdiv->IsMathFloorOfDiv()) {
- Label done;
- Register remainder = scratch0();
- __ mls(remainder, result, right, left);
- __ cmp(remainder, Operand::Zero());
- __ b(eq, &done);
- __ eor(remainder, remainder, Operand(right));
- __ add(result, result, Operand(remainder, ASR, 31));
- __ bind(&done);
- } else if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
+ if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
// Compute remainder and deopt if it's not zero.
Register remainder = scratch0();
- __ mls(remainder, result, right, left);
+ __ mls(remainder, result, divisor, dividend);
__ cmp(remainder, Operand::Zero());
DeoptimizeIf(ne, instr->environment());
}
@@ -1476,19 +1449,21 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
DeoptimizeIf(eq, instr->environment());
}
- if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
- // Note that we could emit branch-free code, but that would need one more
- // register.
- if (divisor == -1) {
- DeoptimizeIf(vs, instr->environment());
- __ mov(result, Operand(dividend, ASR, shift));
- } else {
- __ mov(result, Operand(kMinInt / divisor), LeaveCC, vs);
- __ mov(result, Operand(dividend, ASR, shift), LeaveCC, vc);
- }
- } else {
+
+ // If the negation could not overflow, simply shifting is OK.
+ if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
__ mov(result, Operand(dividend, ASR, shift));
+ return;
+ }
+
+ // Dividing by -1 is basically negation, unless we overflow.
+ if (divisor == -1) {
+ DeoptimizeIf(vs, instr->environment());
+ return;
}
+
+ __ mov(result, Operand(kMinInt / divisor), LeaveCC, vs);
+ __ mov(result, Operand(dividend, ASR, shift), LeaveCC, vc);
}
@@ -1538,6 +1513,69 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
}
+// TODO(svenpanne) Refactor this to avoid code duplication with DoDivI.
+void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
+ HBinaryOperation* hdiv = instr->hydrogen();
+ Register left = ToRegister(instr->dividend());
+ Register right = ToRegister(instr->divisor());
+ Register result = ToRegister(instr->result());
+
+ // Check for x / 0.
+ if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
+ __ cmp(right, Operand::Zero());
+ DeoptimizeIf(eq, instr->environment());
+ }
+
+ // Check for (0 / -x) that will produce negative zero.
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ Label positive;
+ if (!instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
+ // Do the test only if it hadn't be done above.
+ __ cmp(right, Operand::Zero());
+ }
+ __ b(pl, &positive);
+ __ cmp(left, Operand::Zero());
+ DeoptimizeIf(eq, instr->environment());
+ __ bind(&positive);
+ }
+
+ // Check for (kMinInt / -1).
+ if (hdiv->CheckFlag(HValue::kCanOverflow) &&
+ (!CpuFeatures::IsSupported(SUDIV) ||
+ !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+ // We don't need to check for overflow when truncating with sdiv
+ // support because, on ARM, sdiv kMinInt, -1 -> kMinInt.
+ __ cmp(left, Operand(kMinInt));
+ __ cmp(right, Operand(-1), eq);
+ DeoptimizeIf(eq, instr->environment());
+ }
+
+ if (CpuFeatures::IsSupported(SUDIV)) {
+ CpuFeatureScope scope(masm(), SUDIV);
+ __ sdiv(result, left, right);
+ } else {
+ DoubleRegister vleft = ToDoubleRegister(instr->temp());
+ DoubleRegister vright = double_scratch0();
+ __ vmov(double_scratch0().low(), left);
+ __ vcvt_f64_s32(vleft, double_scratch0().low());
+ __ vmov(double_scratch0().low(), right);
+ __ vcvt_f64_s32(vright, double_scratch0().low());
+ __ vdiv(vleft, vleft, vright); // vleft now contains the result.
+ __ vcvt_s32_f64(double_scratch0().low(), vleft);
+ __ vmov(result, double_scratch0().low());
+ }
+
+ Label done;
+ Register remainder = scratch0();
+ __ mls(remainder, result, right, left);
+ __ cmp(remainder, Operand::Zero());
+ __ b(eq, &done);
+ __ eor(remainder, remainder, Operand(right));
+ __ add(result, result, Operand(remainder, ASR, 31));
+ __ bind(&done);
+}
+
+
void LCodeGen::DoMulI(LMulI* instr) {
Register result = ToRegister(instr->result());
// Note that result may alias left.
@@ -1835,9 +1873,16 @@ void LCodeGen::DoConstantE(LConstantE* instr) {
void LCodeGen::DoConstantT(LConstantT* instr) {
- Handle<Object> value = instr->value(isolate());
+ Handle<Object> object = instr->value(isolate());
AllowDeferredHandleDereference smi_check;
- __ Move(ToRegister(instr->result()), value);
+ if (instr->hydrogen()->HasObjectMap()) {
+ Handle<Map> object_map = instr->hydrogen()->ObjectMap().handle();
+ ASSERT(object->IsHeapObject());
+ ASSERT(!object_map->is_stable() ||
+ *object_map == Handle<HeapObject>::cast(object)->map());
+ USE(object_map);
+ }
+ __ Move(ToRegister(instr->result()), object);
}
@@ -2091,11 +2136,11 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
ASSERT(ToRegister(instr->right()).is(r0));
ASSERT(ToRegister(instr->result()).is(r0));
- BinaryOpICStub stub(instr->op(), NO_OVERWRITE);
+ BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE);
// Block literal pool emission to ensure nop indicating no inlined smi code
// is in the correct position.
Assembler::BlockConstPoolScope block_const_pool(masm());
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
@@ -2686,8 +2731,8 @@ void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
ASSERT(ToRegister(instr->left()).is(r0)); // Object is in r0.
ASSERT(ToRegister(instr->right()).is(r1)); // Function is in r1.
- InstanceofStub stub(InstanceofStub::kArgsInRegisters);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
__ cmp(r0, Operand::Zero());
__ mov(r0, Operand(factory()->false_value()), LeaveCC, ne);
@@ -2783,7 +2828,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
flags | InstanceofStub::kCallSiteInlineCheck);
flags = static_cast<InstanceofStub::Flags>(
flags | InstanceofStub::kReturnTrueFalseObject);
- InstanceofStub stub(flags);
+ InstanceofStub stub(isolate(), flags);
PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
LoadContextFromDeferred(instr->context());
@@ -2805,7 +2850,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
ASSERT_EQ(1, masm_->InstructionsGeneratedSince(&before_push_delta));
__ nop();
}
- CallCodeGeneric(stub.GetCode(isolate()),
+ CallCodeGeneric(stub.GetCode(),
RelocInfo::CODE_TARGET,
instr,
RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
@@ -3309,7 +3354,8 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key,
__ add(scratch0(), scratch0(), Operand(key, LSL, shift_size));
} else {
ASSERT_EQ(-1, shift_size);
- __ add(scratch0(), scratch0(), Operand(key, LSR, 1));
+ // key can be negative, so using ASR here.
+ __ add(scratch0(), scratch0(), Operand(key, ASR, 1));
}
return MemOperand(base, scratch0());
}
@@ -3801,7 +3847,7 @@ void LCodeGen::DoPower(LPower* instr) {
ASSERT(ToDoubleRegister(instr->result()).is(d2));
if (exponent_type.IsSmi()) {
- MathPowStub stub(MathPowStub::TAGGED);
+ MathPowStub stub(isolate(), MathPowStub::TAGGED);
__ CallStub(&stub);
} else if (exponent_type.IsTagged()) {
Label no_deopt;
@@ -3811,14 +3857,14 @@ void LCodeGen::DoPower(LPower* instr) {
__ cmp(r6, Operand(ip));
DeoptimizeIf(ne, instr->environment());
__ bind(&no_deopt);
- MathPowStub stub(MathPowStub::TAGGED);
+ MathPowStub stub(isolate(), MathPowStub::TAGGED);
__ CallStub(&stub);
} else if (exponent_type.IsInteger32()) {
- MathPowStub stub(MathPowStub::INTEGER);
+ MathPowStub stub(isolate(), MathPowStub::INTEGER);
__ CallStub(&stub);
} else {
ASSERT(exponent_type.IsDouble());
- MathPowStub stub(MathPowStub::DOUBLE);
+ MathPowStub stub(isolate(), MathPowStub::DOUBLE);
__ CallStub(&stub);
}
}
@@ -3925,8 +3971,8 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
ASSERT(ToRegister(instr->result()).is(r0));
int arity = instr->arity();
- CallFunctionStub stub(arity, instr->hydrogen()->function_flags());
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
@@ -3938,8 +3984,8 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
__ mov(r0, Operand(instr->arity()));
// No cell in r2 for construct type feedback in optimized code
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
- CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
}
@@ -3957,8 +4003,8 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
: DONT_OVERRIDE;
if (instr->arity() == 0) {
- ArrayNoArgumentConstructorStub stub(kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
} else if (instr->arity() == 1) {
Label done;
if (IsFastPackedElementsKind(kind)) {
@@ -3970,18 +4016,20 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
__ b(eq, &packed_case);
ElementsKind holey_kind = GetHoleyElementsKind(kind);
- ArraySingleArgumentConstructorStub stub(holey_kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArraySingleArgumentConstructorStub stub(isolate(),
+ holey_kind,
+ override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
__ jmp(&done);
__ bind(&packed_case);
}
- ArraySingleArgumentConstructorStub stub(kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
__ bind(&done);
} else {
- ArrayNArgumentsConstructorStub stub(kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
}
}
@@ -4028,7 +4076,6 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
return;
}
- Handle<Map> transition = instr->transition();
SmiCheck check_needed =
instr->hydrogen()->value()->IsHeapObject()
? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
@@ -4042,19 +4089,21 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
__ SmiTst(value);
DeoptimizeIf(eq, instr->environment());
- // We know that value is a smi now, so we can omit the check below.
+ // We know now that value is not a smi, so we can omit the check below.
check_needed = OMIT_SMI_CHECK;
}
} else if (representation.IsDouble()) {
- ASSERT(transition.is_null());
ASSERT(access.IsInobject());
+ ASSERT(!instr->hydrogen()->has_transition());
ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
DwVfpRegister value = ToDoubleRegister(instr->value());
__ vstr(value, FieldMemOperand(object, offset));
return;
}
- if (!transition.is_null()) {
+ if (instr->hydrogen()->has_transition()) {
+ Handle<Map> transition = instr->hydrogen()->transition_map();
+ AddDeprecationDependency(transition);
__ mov(scratch, Operand(transition));
__ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
@@ -4119,38 +4168,29 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
}
-void LCodeGen::ApplyCheckIf(Condition condition, LBoundsCheck* check) {
- if (FLAG_debug_code && check->hydrogen()->skip_check()) {
+void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
+ Condition cc = instr->hydrogen()->allow_equality() ? hi : hs;
+ if (instr->index()->IsConstantOperand()) {
+ Operand index = ToOperand(instr->index());
+ Register length = ToRegister(instr->length());
+ __ cmp(length, index);
+ cc = ReverseCondition(cc);
+ } else {
+ Register index = ToRegister(instr->index());
+ Operand length = ToOperand(instr->length());
+ __ cmp(index, length);
+ }
+ if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
Label done;
- __ b(NegateCondition(condition), &done);
+ __ b(NegateCondition(cc), &done);
__ stop("eliminated bounds check failed");
__ bind(&done);
} else {
- DeoptimizeIf(condition, check->environment());
+ DeoptimizeIf(cc, instr->environment());
}
}
-void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
- if (instr->hydrogen()->skip_check()) return;
-
- if (instr->index()->IsConstantOperand()) {
- int constant_index =
- ToInteger32(LConstantOperand::cast(instr->index()));
- if (instr->hydrogen()->length()->representation().IsSmi()) {
- __ mov(ip, Operand(Smi::FromInt(constant_index)));
- } else {
- __ mov(ip, Operand(constant_index));
- }
- __ cmp(ip, ToRegister(instr->length()));
- } else {
- __ cmp(ToRegister(instr->index()), ToRegister(instr->length()));
- }
- Condition condition = instr->hydrogen()->allow_equality() ? hi : hs;
- ApplyCheckIf(condition, instr);
-}
-
-
void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
Register external_pointer = ToRegister(instr->elements());
Register key = no_reg;
@@ -4381,15 +4421,15 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
scratch, GetLinkRegisterState(), kDontSaveFPRegs);
} else {
ASSERT(ToRegister(instr->context()).is(cp));
+ ASSERT(object_reg.is(r0));
PushSafepointRegistersScope scope(
this, Safepoint::kWithRegistersAndDoubles);
- __ Move(r0, object_reg);
__ Move(r1, to_map);
bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
- TransitionElementsKindStub stub(from_kind, to_kind, is_js_array);
+ TransitionElementsKindStub stub(isolate(), from_kind, to_kind, is_js_array);
__ CallStub(&stub);
RecordSafepointWithRegistersAndDoubles(
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
+ instr->pointer_map(), 0, Safepoint::kLazyDeopt);
}
__ bind(&not_applicable);
}
@@ -4409,9 +4449,10 @@ void LCodeGen::DoStringAdd(LStringAdd* instr) {
ASSERT(ToRegister(instr->context()).is(cp));
ASSERT(ToRegister(instr->left()).is(r1));
ASSERT(ToRegister(instr->right()).is(r0));
- StringAddStub stub(instr->hydrogen()->flags(),
+ StringAddStub stub(isolate(),
+ instr->hydrogen()->flags(),
instr->hydrogen()->pretenure_flag());
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
@@ -5106,7 +5147,14 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
Register object_;
};
- if (instr->hydrogen()->CanOmitMapChecks()) return;
+ if (instr->hydrogen()->IsStabilityCheck()) {
+ const UniqueSet<Map>* maps = instr->hydrogen()->maps();
+ for (int i = 0; i < maps->size(); ++i) {
+ AddStabilityDependency(maps->at(i).handle());
+ }
+ return;
+ }
+
Register map_reg = scratch0();
LOperand* input = instr->value();
@@ -5116,22 +5164,22 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
__ ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
DeferredCheckMaps* deferred = NULL;
- if (instr->hydrogen()->has_migration_target()) {
+ if (instr->hydrogen()->HasMigrationTarget()) {
deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
__ bind(deferred->check_maps());
}
- UniqueSet<Map> map_set = instr->hydrogen()->map_set();
+ const UniqueSet<Map>* maps = instr->hydrogen()->maps();
Label success;
- for (int i = 0; i < map_set.size() - 1; i++) {
- Handle<Map> map = map_set.at(i).handle();
+ for (int i = 0; i < maps->size() - 1; i++) {
+ Handle<Map> map = maps->at(i).handle();
__ CompareMap(map_reg, map, &success);
__ b(eq, &success);
}
- Handle<Map> map = map_set.at(map_set.size() - 1).handle();
+ Handle<Map> map = maps->at(maps->size() - 1).handle();
__ CompareMap(map_reg, map, &success);
- if (instr->hydrogen()->has_migration_target()) {
+ if (instr->hydrogen()->HasMigrationTarget()) {
__ b(ne, deferred->entry());
} else {
DeoptimizeIf(ne, instr->environment());
@@ -5301,7 +5349,13 @@ void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
__ push(size);
} else {
int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
- __ Push(Smi::FromInt(size));
+ if (size >= 0 && size <= Smi::kMaxValue) {
+ __ Push(Smi::FromInt(size));
+ } else {
+ // We should never get here at runtime => abort
+ __ stop("invalid allocation size");
+ return;
+ }
}
int flags = AllocateDoubleAlignFlag::encode(
@@ -5381,10 +5435,11 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
// space for nested functions that don't need literals cloning.
bool pretenure = instr->hydrogen()->pretenure();
if (!pretenure && instr->hydrogen()->has_no_literals()) {
- FastNewClosureStub stub(instr->hydrogen()->strict_mode(),
+ FastNewClosureStub stub(isolate(),
+ instr->hydrogen()->strict_mode(),
instr->hydrogen()->is_generator());
__ mov(r2, Operand(instr->hydrogen()->shared_info()));
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
} else {
__ mov(r2, Operand(instr->hydrogen()->shared_info()));
__ mov(r1, Operand(pretenure ? factory()->true_value()
@@ -5421,13 +5476,14 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
Handle<String> type_name) {
Condition final_branch_condition = kNoCondition;
Register scratch = scratch0();
- if (type_name->Equals(heap()->number_string())) {
+ Factory* factory = isolate()->factory();
+ if (String::Equals(type_name, factory->number_string())) {
__ JumpIfSmi(input, true_label);
__ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
__ CompareRoot(scratch, Heap::kHeapNumberMapRootIndex);
final_branch_condition = eq;
- } else if (type_name->Equals(heap()->string_string())) {
+ } else if (String::Equals(type_name, factory->string_string())) {
__ JumpIfSmi(input, false_label);
__ CompareObjectType(input, scratch, no_reg, FIRST_NONSTRING_TYPE);
__ b(ge, false_label);
@@ -5435,22 +5491,23 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
__ tst(scratch, Operand(1 << Map::kIsUndetectable));
final_branch_condition = eq;
- } else if (type_name->Equals(heap()->symbol_string())) {
+ } else if (String::Equals(type_name, factory->symbol_string())) {
__ JumpIfSmi(input, false_label);
__ CompareObjectType(input, scratch, no_reg, SYMBOL_TYPE);
final_branch_condition = eq;
- } else if (type_name->Equals(heap()->boolean_string())) {
+ } else if (String::Equals(type_name, factory->boolean_string())) {
__ CompareRoot(input, Heap::kTrueValueRootIndex);
__ b(eq, true_label);
__ CompareRoot(input, Heap::kFalseValueRootIndex);
final_branch_condition = eq;
- } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) {
+ } else if (FLAG_harmony_typeof &&
+ String::Equals(type_name, factory->null_string())) {
__ CompareRoot(input, Heap::kNullValueRootIndex);
final_branch_condition = eq;
- } else if (type_name->Equals(heap()->undefined_string())) {
+ } else if (String::Equals(type_name, factory->undefined_string())) {
__ CompareRoot(input, Heap::kUndefinedValueRootIndex);
__ b(eq, true_label);
__ JumpIfSmi(input, false_label);
@@ -5460,7 +5517,7 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
__ tst(scratch, Operand(1 << Map::kIsUndetectable));
final_branch_condition = ne;
- } else if (type_name->Equals(heap()->function_string())) {
+ } else if (String::Equals(type_name, factory->function_string())) {
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
Register type_reg = scratch;
__ JumpIfSmi(input, false_label);
@@ -5469,7 +5526,7 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
__ cmp(type_reg, Operand(JS_FUNCTION_PROXY_TYPE));
final_branch_condition = eq;
- } else if (type_name->Equals(heap()->object_string())) {
+ } else if (String::Equals(type_name, factory->object_string())) {
Register map = scratch;
__ JumpIfSmi(input, false_label);
if (!FLAG_harmony_typeof) {
@@ -5607,12 +5664,12 @@ void LCodeGen::DoStackCheck(LStackCheck* instr) {
__ LoadRoot(ip, Heap::kStackLimitRootIndex);
__ cmp(sp, Operand(ip));
__ b(hs, &done);
- PredictableCodeSizeScope predictable(masm_, 2 * Assembler::kInstrSize);
+ Handle<Code> stack_check = isolate()->builtins()->StackCheck();
+ PredictableCodeSizeScope predictable(masm(),
+ CallCodeSize(stack_check, RelocInfo::CODE_TARGET));
ASSERT(instr->context()->IsRegister());
ASSERT(ToRegister(instr->context()).is(cp));
- CallCode(isolate()->builtins()->StackCheck(),
- RelocInfo::CODE_TARGET,
- instr);
+ CallCode(stack_check, RelocInfo::CODE_TARGET, instr);
__ bind(&done);
} else {
ASSERT(instr->hydrogen()->is_backwards_branch());
@@ -5716,13 +5773,61 @@ void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
}
+void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
+ Register result,
+ Register object,
+ Register index) {
+ PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
+ __ Push(object);
+ __ Push(index);
+ __ mov(cp, Operand::Zero());
+ __ CallRuntimeSaveDoubles(Runtime::kLoadMutableDouble);
+ RecordSafepointWithRegisters(
+ instr->pointer_map(), 2, Safepoint::kNoLazyDeopt);
+ __ StoreToSafepointRegisterSlot(r0, result);
+}
+
+
void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
+ class DeferredLoadMutableDouble V8_FINAL : public LDeferredCode {
+ public:
+ DeferredLoadMutableDouble(LCodeGen* codegen,
+ LLoadFieldByIndex* instr,
+ Register result,
+ Register object,
+ Register index)
+ : LDeferredCode(codegen),
+ instr_(instr),
+ result_(result),
+ object_(object),
+ index_(index) {
+ }
+ virtual void Generate() V8_OVERRIDE {
+ codegen()->DoDeferredLoadMutableDouble(instr_, result_, object_, index_);
+ }
+ virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
+ private:
+ LLoadFieldByIndex* instr_;
+ Register result_;
+ Register object_;
+ Register index_;
+ };
+
Register object = ToRegister(instr->object());
Register index = ToRegister(instr->index());
Register result = ToRegister(instr->result());
Register scratch = scratch0();
+ DeferredLoadMutableDouble* deferred;
+ deferred = new(zone()) DeferredLoadMutableDouble(
+ this, instr, result, object, index);
+
Label out_of_object, done;
+
+ __ tst(index, Operand(Smi::FromInt(1)));
+ __ b(ne, deferred->entry());
+ __ mov(index, Operand(index, ASR, 1));
+
__ cmp(index, Operand::Zero());
__ b(lt, &out_of_object);
@@ -5738,6 +5843,7 @@ void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
__ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index));
__ ldr(result, FieldMemOperand(scratch,
FixedArray::kHeaderSize - kPointerSize));
+ __ bind(deferred->exit());
__ bind(&done);
}
diff --git a/deps/v8/src/arm/lithium-codegen-arm.h b/deps/v8/src/arm/lithium-codegen-arm.h
index 21da500d01..3e05c328cb 100644
--- a/deps/v8/src/arm/lithium-codegen-arm.h
+++ b/deps/v8/src/arm/lithium-codegen-arm.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM_LITHIUM_CODEGEN_ARM_H_
#define V8_ARM_LITHIUM_CODEGEN_ARM_H_
@@ -35,7 +12,7 @@
#include "lithium-codegen.h"
#include "safepoint-table.h"
#include "scopes.h"
-#include "v8utils.h"
+#include "utils.h"
namespace v8 {
namespace internal {
@@ -141,6 +118,10 @@ class LCodeGen: public LCodeGenBase {
void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
Label* map_check);
void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
+ void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
+ Register result,
+ Register object,
+ Register index);
// Parallel move support.
void DoParallelMove(LParallelMove* move);
@@ -182,8 +163,6 @@ class LCodeGen: public LCodeGenBase {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
- void Abort(BailoutReason reason);
-
void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
void SaveCallerDoubles();
@@ -205,6 +184,8 @@ class LCodeGen: public LCodeGenBase {
RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
};
+ int CallCodeSize(Handle<Code> code, RelocInfo::Mode mode);
+
void CallCode(
Handle<Code> code,
RelocInfo::Mode mode,
@@ -258,7 +239,6 @@ class LCodeGen: public LCodeGenBase {
LEnvironment* environment,
Deoptimizer::BailoutType bailout_type);
void DeoptimizeIf(Condition condition, LEnvironment* environment);
- void ApplyCheckIf(Condition condition, LBoundsCheck* check);
void AddToTranslation(LEnvironment* environment,
Translation* translation,
diff --git a/deps/v8/src/arm/lithium-gap-resolver-arm.cc b/deps/v8/src/arm/lithium-gap-resolver-arm.cc
index 0c6b2adadf..fe0ef144ab 100644
--- a/deps/v8/src/arm/lithium-gap-resolver-arm.cc
+++ b/deps/v8/src/arm/lithium-gap-resolver-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -33,11 +10,22 @@
namespace v8 {
namespace internal {
-static const Register kSavedValueRegister = { 9 };
+// We use the root register to spill a value while breaking a cycle in parallel
+// moves. We don't need access to roots while resolving the move list and using
+// the root register has two advantages:
+// - It is not in crankshaft allocatable registers list, so it can't interfere
+// with any of the moves we are resolving.
+// - We don't need to push it on the stack, as we can reload it with its value
+// once we have resolved a cycle.
+#define kSavedValueRegister kRootRegister
+
LGapResolver::LGapResolver(LCodeGen* owner)
: cgen_(owner), moves_(32, owner->zone()), root_index_(0), in_cycle_(false),
- saved_destination_(NULL) { }
+ saved_destination_(NULL), need_to_restore_root_(false) { }
+
+
+#define __ ACCESS_MASM(cgen_->masm())
void LGapResolver::Resolve(LParallelMove* parallel_move) {
@@ -67,6 +55,12 @@ void LGapResolver::Resolve(LParallelMove* parallel_move) {
}
}
+ if (need_to_restore_root_) {
+ ASSERT(kSavedValueRegister.is(kRootRegister));
+ __ InitializeRootRegister();
+ need_to_restore_root_ = false;
+ }
+
moves_.Rewind(0);
}
@@ -155,20 +149,21 @@ void LGapResolver::Verify() {
#endif
}
-#define __ ACCESS_MASM(cgen_->masm())
void LGapResolver::BreakCycle(int index) {
- // We save in a register the value that should end up in the source of
- // moves_[root_index]. After performing all moves in the tree rooted
- // in that move, we save the value to that source.
+ // We save in a register the source of that move and we remember its
+ // destination. Then we mark this move as resolved so the cycle is
+ // broken and we can perform the other moves.
ASSERT(moves_[index].destination()->Equals(moves_[root_index_].source()));
ASSERT(!in_cycle_);
in_cycle_ = true;
LOperand* source = moves_[index].source();
saved_destination_ = moves_[index].destination();
if (source->IsRegister()) {
+ need_to_restore_root_ = true;
__ mov(kSavedValueRegister, cgen_->ToRegister(source));
} else if (source->IsStackSlot()) {
+ need_to_restore_root_ = true;
__ ldr(kSavedValueRegister, cgen_->ToMemOperand(source));
} else if (source->IsDoubleRegister()) {
__ vmov(kScratchDoubleReg, cgen_->ToDoubleRegister(source));
@@ -186,7 +181,6 @@ void LGapResolver::RestoreValue() {
ASSERT(in_cycle_);
ASSERT(saved_destination_ != NULL);
- // Spilled value is in kSavedValueRegister or kSavedDoubleValueRegister.
if (saved_destination_->IsRegister()) {
__ mov(cgen_->ToRegister(saved_destination_), kSavedValueRegister);
} else if (saved_destination_->IsStackSlot()) {
@@ -226,20 +220,15 @@ void LGapResolver::EmitMove(int index) {
} else {
ASSERT(destination->IsStackSlot());
MemOperand destination_operand = cgen_->ToMemOperand(destination);
- if (in_cycle_) {
- if (!destination_operand.OffsetIsUint12Encodable()) {
- // ip is overwritten while saving the value to the destination.
- // Therefore we can't use ip. It is OK if the read from the source
- // destroys ip, since that happens before the value is read.
- __ vldr(kScratchDoubleReg.low(), source_operand);
- __ vstr(kScratchDoubleReg.low(), destination_operand);
- } else {
- __ ldr(ip, source_operand);
- __ str(ip, destination_operand);
- }
+ if (!destination_operand.OffsetIsUint12Encodable()) {
+ // ip is overwritten while saving the value to the destination.
+ // Therefore we can't use ip. It is OK if the read from the source
+ // destroys ip, since that happens before the value is read.
+ __ vldr(kScratchDoubleReg.low(), source_operand);
+ __ vstr(kScratchDoubleReg.low(), destination_operand);
} else {
- __ ldr(kSavedValueRegister, source_operand);
- __ str(kSavedValueRegister, destination_operand);
+ __ ldr(ip, source_operand);
+ __ str(ip, destination_operand);
}
}
@@ -261,14 +250,14 @@ void LGapResolver::EmitMove(int index) {
} else {
ASSERT(destination->IsStackSlot());
ASSERT(!in_cycle_); // Constant moves happen after all cycles are gone.
+ need_to_restore_root_ = true;
Representation r = cgen_->IsSmi(constant_source)
? Representation::Smi() : Representation::Integer32();
if (cgen_->IsInteger32(constant_source)) {
__ mov(kSavedValueRegister,
Operand(cgen_->ToRepresentation(constant_source, r)));
} else {
- __ Move(kSavedValueRegister,
- cgen_->ToHandle(constant_source));
+ __ Move(kSavedValueRegister, cgen_->ToHandle(constant_source));
}
__ str(kSavedValueRegister, cgen_->ToMemOperand(destination));
}
@@ -290,16 +279,11 @@ void LGapResolver::EmitMove(int index) {
ASSERT(destination->IsDoubleStackSlot());
MemOperand destination_operand = cgen_->ToMemOperand(destination);
if (in_cycle_) {
- // kSavedDoubleValueRegister was used to break the cycle,
- // but kSavedValueRegister is free.
- MemOperand source_high_operand =
- cgen_->ToHighMemOperand(source);
- MemOperand destination_high_operand =
- cgen_->ToHighMemOperand(destination);
- __ ldr(kSavedValueRegister, source_operand);
- __ str(kSavedValueRegister, destination_operand);
- __ ldr(kSavedValueRegister, source_high_operand);
- __ str(kSavedValueRegister, destination_high_operand);
+ // kScratchDoubleReg was used to break the cycle.
+ __ vstm(db_w, sp, kScratchDoubleReg, kScratchDoubleReg);
+ __ vldr(kScratchDoubleReg, source_operand);
+ __ vstr(kScratchDoubleReg, destination_operand);
+ __ vldm(ia_w, sp, kScratchDoubleReg, kScratchDoubleReg);
} else {
__ vldr(kScratchDoubleReg, source_operand);
__ vstr(kScratchDoubleReg, destination_operand);
diff --git a/deps/v8/src/arm/lithium-gap-resolver-arm.h b/deps/v8/src/arm/lithium-gap-resolver-arm.h
index 044c2864a4..73914e4daf 100644
--- a/deps/v8/src/arm/lithium-gap-resolver-arm.h
+++ b/deps/v8/src/arm/lithium-gap-resolver-arm.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM_LITHIUM_GAP_RESOLVER_ARM_H_
#define V8_ARM_LITHIUM_GAP_RESOLVER_ARM_H_
@@ -76,6 +53,10 @@ class LGapResolver V8_FINAL BASE_EMBEDDED {
int root_index_;
bool in_cycle_;
LOperand* saved_destination_;
+
+ // We use the root register as a scratch in a few places. When that happens,
+ // this flag is set to indicate that it needs to be restored.
+ bool need_to_restore_root_;
};
} } // namespace v8::internal
diff --git a/deps/v8/src/arm/macro-assembler-arm.cc b/deps/v8/src/arm/macro-assembler-arm.cc
index 2bfe09f768..9752622447 100644
--- a/deps/v8/src/arm/macro-assembler-arm.cc
+++ b/deps/v8/src/arm/macro-assembler-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <limits.h> // For LONG_MIN, LONG_MAX.
@@ -100,19 +77,31 @@ int MacroAssembler::CallSize(
int size = 2 * kInstrSize;
Instr mov_instr = cond | MOV | LeaveCC;
intptr_t immediate = reinterpret_cast<intptr_t>(target);
- if (!Operand(immediate, rmode).is_single_instruction(this, mov_instr)) {
+ if (!Operand(immediate, rmode).is_single_instruction(isolate(),
+ this,
+ mov_instr)) {
size += kInstrSize;
}
return size;
}
-int MacroAssembler::CallSizeNotPredictableCodeSize(
- Address target, RelocInfo::Mode rmode, Condition cond) {
+int MacroAssembler::CallStubSize(
+ CodeStub* stub, TypeFeedbackId ast_id, Condition cond) {
+ return CallSize(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id, cond);
+}
+
+
+int MacroAssembler::CallSizeNotPredictableCodeSize(Isolate* isolate,
+ Address target,
+ RelocInfo::Mode rmode,
+ Condition cond) {
int size = 2 * kInstrSize;
Instr mov_instr = cond | MOV | LeaveCC;
intptr_t immediate = reinterpret_cast<intptr_t>(target);
- if (!Operand(immediate, rmode).is_single_instruction(NULL, mov_instr)) {
+ if (!Operand(immediate, rmode).is_single_instruction(isolate,
+ NULL,
+ mov_instr)) {
size += kInstrSize;
}
return size;
@@ -272,11 +261,11 @@ void MacroAssembler::Move(DwVfpRegister dst, DwVfpRegister src) {
void MacroAssembler::And(Register dst, Register src1, const Operand& src2,
Condition cond) {
if (!src2.is_reg() &&
- !src2.must_output_reloc_info(this) &&
+ !src2.must_output_reloc_info(isolate(), this) &&
src2.immediate() == 0) {
mov(dst, Operand::Zero(), LeaveCC, cond);
- } else if (!src2.is_single_instruction(this) &&
- !src2.must_output_reloc_info(this) &&
+ } else if (!src2.is_single_instruction(isolate(), this) &&
+ !src2.must_output_reloc_info(isolate(), this) &&
CpuFeatures::IsSupported(ARMv7) &&
IsPowerOf2(src2.immediate() + 1)) {
ubfx(dst, src1, 0,
@@ -549,7 +538,8 @@ void MacroAssembler::RecordWrite(Register object,
if (lr_status == kLRHasNotBeenSaved) {
push(lr);
}
- RecordWriteStub stub(object, value, address, remembered_set_action, fp_mode);
+ RecordWriteStub stub(isolate(), object, value, address, remembered_set_action,
+ fp_mode);
CallStub(&stub);
if (lr_status == kLRHasNotBeenSaved) {
pop(lr);
@@ -598,7 +588,7 @@ void MacroAssembler::RememberedSetHelper(Register object, // For debug tests.
}
push(lr);
StoreBufferOverflowStub store_buffer_overflow =
- StoreBufferOverflowStub(fp_mode);
+ StoreBufferOverflowStub(isolate(), fp_mode);
CallStub(&store_buffer_overflow);
pop(lr);
bind(&done);
@@ -650,7 +640,7 @@ void MacroAssembler::PopSafepointRegisters() {
void MacroAssembler::PushSafepointRegistersAndDoubles() {
// Number of d-regs not known at snapshot time.
- ASSERT(!Serializer::enabled());
+ ASSERT(!Serializer::enabled(isolate()));
PushSafepointRegisters();
// Only save allocatable registers.
ASSERT(kScratchDoubleReg.is(d15) && kDoubleRegZero.is(d14));
@@ -664,7 +654,7 @@ void MacroAssembler::PushSafepointRegistersAndDoubles() {
void MacroAssembler::PopSafepointRegistersAndDoubles() {
// Number of d-regs not known at snapshot time.
- ASSERT(!Serializer::enabled());
+ ASSERT(!Serializer::enabled(isolate()));
// Only save allocatable registers.
ASSERT(kScratchDoubleReg.is(d15) && kDoubleRegZero.is(d14));
ASSERT(DwVfpRegister::NumReservedRegisters() == 2);
@@ -706,7 +696,7 @@ MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) {
MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) {
// Number of d-regs not known at snapshot time.
- ASSERT(!Serializer::enabled());
+ ASSERT(!Serializer::enabled(isolate()));
// General purpose registers are pushed last on the stack.
int doubles_size = DwVfpRegister::NumAllocatableRegisters() * kDoubleSize;
int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize;
@@ -789,6 +779,14 @@ void MacroAssembler::VFPEnsureFPSCRState(Register scratch) {
// If needed, restore wanted bits of FPSCR.
Label fpscr_done;
vmrs(scratch);
+ if (emit_debug_code()) {
+ Label rounding_mode_correct;
+ tst(scratch, Operand(kVFPRoundingModeMask));
+ b(eq, &rounding_mode_correct);
+ // Don't call Assert here, since Runtime_Abort could re-enter here.
+ stop("Default rounding mode not set");
+ bind(&rounding_mode_correct);
+ }
tst(scratch, Operand(kVFPDefaultNaNModeControlBit));
b(ne, &fpscr_done);
orr(scratch, scratch, Operand(kVFPDefaultNaNModeControlBit));
@@ -912,7 +910,7 @@ void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
} else {
PredictableCodeSizeScope predictible_code_size_scope(
- this, kNoCodeAgeSequenceLength * Assembler::kInstrSize);
+ this, kNoCodeAgeSequenceLength);
// The following three instructions must remain together and unmodified
// for code aging to work properly.
if (isolate()->IsCodePreAgingActive()) {
@@ -989,7 +987,6 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
}
if (FLAG_enable_ool_constant_pool) {
str(pp, MemOperand(fp, ExitFrameConstants::kConstantPoolOffset));
- LoadConstantPoolPointerRegister();
}
mov(ip, Operand(CodeObject()));
str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset));
@@ -1321,15 +1318,13 @@ void MacroAssembler::IsObjectNameType(Register object,
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
void MacroAssembler::DebugBreak() {
mov(r0, Operand::Zero());
mov(r1, Operand(ExternalReference(Runtime::kDebugBreak, isolate())));
- CEntryStub ces(1);
+ CEntryStub ces(isolate(), 1);
ASSERT(AllowThisStubCall(&ces));
- Call(ces.GetCode(isolate()), RelocInfo::DEBUG_BREAK);
+ Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
}
-#endif
void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
@@ -1755,7 +1750,7 @@ void MacroAssembler::Allocate(int object_size,
object_size -= bits;
shift += 8;
Operand bits_operand(bits);
- ASSERT(bits_operand.is_single_instruction(this));
+ ASSERT(bits_operand.is_single_instruction(isolate(), this));
add(scratch2, source, bits_operand, SetCC, cond);
source = scratch2;
cond = cc;
@@ -2305,12 +2300,12 @@ void MacroAssembler::CallStub(CodeStub* stub,
TypeFeedbackId ast_id,
Condition cond) {
ASSERT(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs.
- Call(stub->GetCode(isolate()), RelocInfo::CODE_TARGET, ast_id, cond);
+ Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id, cond);
}
void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) {
- Jump(stub->GetCode(isolate()), RelocInfo::CODE_TARGET, cond);
+ Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond);
}
@@ -2339,10 +2334,7 @@ void MacroAssembler::CallApiFunctionAndReturn(
Label profiler_disabled;
Label end_profiler_check;
- bool* is_profiling_flag =
- isolate()->cpu_profiler()->is_profiling_address();
- STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
- mov(r9, Operand(reinterpret_cast<int32_t>(is_profiling_flag)));
+ mov(r9, Operand(ExternalReference::is_profiling_address(isolate())));
ldrb(r9, MemOperand(r9, 0));
cmp(r9, Operand(0));
b(eq, &profiler_disabled);
@@ -2375,7 +2367,7 @@ void MacroAssembler::CallApiFunctionAndReturn(
// Native call returns to the DirectCEntry stub which redirects to the
// return address pushed on stack (could have moved after GC).
// DirectCEntry stub itself is generated early and never moves.
- DirectCEntryStub stub;
+ DirectCEntryStub stub(isolate());
stub.GenerateCall(this, r3);
if (FLAG_log_timer_events) {
@@ -2455,14 +2447,6 @@ bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
}
-void MacroAssembler::IllegalOperation(int num_arguments) {
- if (num_arguments > 0) {
- add(sp, sp, Operand(num_arguments * kPointerSize));
- }
- LoadRoot(r0, Heap::kUndefinedValueRootIndex);
-}
-
-
void MacroAssembler::IndexFromHash(Register hash, Register index) {
// If the hash field contains an array index pick it out. The assert checks
// that the constants for the maximum number of digits for an array index
@@ -2580,7 +2564,7 @@ void MacroAssembler::TruncateDoubleToI(Register result,
sub(sp, sp, Operand(kDoubleSize)); // Put input on stack.
vstr(double_input, MemOperand(sp, 0));
- DoubleToIStub stub(sp, result, 0, true, true);
+ DoubleToIStub stub(isolate(), sp, result, 0, true, true);
CallStub(&stub);
add(sp, sp, Operand(kDoubleSize));
@@ -2602,7 +2586,8 @@ void MacroAssembler::TruncateHeapNumberToI(Register result,
// If we fell through then inline version didn't succeed - call stub instead.
push(lr);
- DoubleToIStub stub(object,
+ DoubleToIStub stub(isolate(),
+ object,
result,
HeapNumber::kValueOffset - kHeapObjectTag,
true,
@@ -2657,10 +2642,7 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f,
// If the expected number of arguments of the runtime function is
// constant, we check that the actual number of arguments match the
// expectation.
- if (f->nargs >= 0 && f->nargs != num_arguments) {
- IllegalOperation(num_arguments);
- return;
- }
+ CHECK(f->nargs < 0 || f->nargs == num_arguments);
// TODO(1236192): Most runtime routines don't need the number of
// arguments passed in because it is constant. At some point we
@@ -2668,7 +2650,7 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f,
// smarter.
mov(r0, Operand(num_arguments));
mov(r1, Operand(ExternalReference(f, isolate())));
- CEntryStub stub(1, save_doubles);
+ CEntryStub stub(isolate(), 1, save_doubles);
CallStub(&stub);
}
@@ -2678,7 +2660,7 @@ void MacroAssembler::CallExternalReference(const ExternalReference& ext,
mov(r0, Operand(num_arguments));
mov(r1, Operand(ext));
- CEntryStub stub(1);
+ CEntryStub stub(isolate(), 1);
CallStub(&stub);
}
@@ -2710,8 +2692,8 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) {
ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1);
#endif
mov(r1, Operand(builtin));
- CEntryStub stub(1);
- Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
+ CEntryStub stub(isolate(), 1);
+ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
}
@@ -3794,36 +3776,19 @@ void MacroAssembler::ClampUint8(Register output_reg, Register input_reg) {
void MacroAssembler::ClampDoubleToUint8(Register result_reg,
DwVfpRegister input_reg,
LowDwVfpRegister double_scratch) {
- Label above_zero;
Label done;
- Label in_bounds;
-
- VFPCompareAndSetFlags(input_reg, 0.0);
- b(gt, &above_zero);
- // Double value is less than zero, NaN or Inf, return 0.
- mov(result_reg, Operand::Zero());
- b(al, &done);
-
- // Double value is >= 255, return 255.
- bind(&above_zero);
+ // Handle inputs >= 255 (including +infinity).
Vmov(double_scratch, 255.0, result_reg);
- VFPCompareAndSetFlags(input_reg, double_scratch);
- b(le, &in_bounds);
mov(result_reg, Operand(255));
- b(al, &done);
-
- // In 0-255 range, round and truncate.
- bind(&in_bounds);
- // Save FPSCR.
- vmrs(ip);
- // Set rounding mode to round to the nearest integer by clearing bits[23:22].
- bic(result_reg, ip, Operand(kVFPRoundingModeMask));
- vmsr(result_reg);
- vcvt_s32_f64(double_scratch.low(), input_reg, kFPSCRRounding);
+ VFPCompareAndSetFlags(input_reg, double_scratch);
+ b(ge, &done);
+
+ // For inputs < 255 (including negative) vcvt_u32_f64 with round-to-nearest
+ // rounding mode will provide the correct result.
+ vcvt_u32_f64(double_scratch.low(), input_reg, kFPSCRRounding);
vmov(result_reg, double_scratch.low());
- // Restore FPSCR.
- vmsr(ip);
+
bind(&done);
}
diff --git a/deps/v8/src/arm/macro-assembler-arm.h b/deps/v8/src/arm/macro-assembler-arm.h
index 6b6ecd32da..ba6f82571d 100644
--- a/deps/v8/src/arm/macro-assembler-arm.h
+++ b/deps/v8/src/arm/macro-assembler-arm.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM_MACRO_ASSEMBLER_ARM_H_
#define V8_ARM_MACRO_ASSEMBLER_ARM_H_
@@ -102,7 +79,11 @@ class MacroAssembler: public Assembler {
static int CallSize(Register target, Condition cond = al);
void Call(Register target, Condition cond = al);
int CallSize(Address target, RelocInfo::Mode rmode, Condition cond = al);
- static int CallSizeNotPredictableCodeSize(Address target,
+ int CallStubSize(CodeStub* stub,
+ TypeFeedbackId ast_id = TypeFeedbackId::None(),
+ Condition cond = al);
+ static int CallSizeNotPredictableCodeSize(Isolate* isolate,
+ Address target,
RelocInfo::Mode rmode,
Condition cond = al);
void Call(Address target, RelocInfo::Mode rmode,
@@ -627,12 +608,10 @@ class MacroAssembler: public Assembler {
Register scratch,
Label* fail);
-#ifdef ENABLE_DEBUGGER_SUPPORT
// ---------------------------------------------------------------------------
// Debugger Support
void DebugBreak();
-#endif
// ---------------------------------------------------------------------------
// Exception handling
@@ -951,10 +930,6 @@ class MacroAssembler: public Assembler {
}
- // Generates code for reporting that an illegal operation has
- // occurred.
- void IllegalOperation(int num_arguments);
-
// Picks out an array index from the hash field.
// Register use:
// hash - holds the index's hash. Clobbered.
@@ -1524,11 +1499,12 @@ class FrameAndConstantPoolScope {
type_(type),
old_has_frame_(masm->has_frame()),
old_constant_pool_available_(masm->is_constant_pool_available()) {
+ // We only want to enable constant pool access for non-manual frame scopes
+ // to ensure the constant pool pointer is valid throughout the scope.
+ ASSERT(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
masm->set_has_frame(true);
masm->set_constant_pool_available(true);
- if (type_ != StackFrame::MANUAL && type_ != StackFrame::NONE) {
- masm->EnterFrame(type, !old_constant_pool_available_);
- }
+ masm->EnterFrame(type, !old_constant_pool_available_);
}
~FrameAndConstantPoolScope() {
diff --git a/deps/v8/src/arm/regexp-macro-assembler-arm.cc b/deps/v8/src/arm/regexp-macro-assembler-arm.cc
index cbc34e10b9..e511554eff 100644
--- a/deps/v8/src/arm/regexp-macro-assembler-arm.cc
+++ b/deps/v8/src/arm/regexp-macro-assembler-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -1043,7 +1020,7 @@ void RegExpMacroAssemblerARM::CallCheckStackGuardState(Register scratch) {
ExternalReference stack_guard_check =
ExternalReference::re_check_stack_guard_state(isolate());
__ mov(ip, Operand(stack_guard_check));
- DirectCEntryStub stub;
+ DirectCEntryStub stub(isolate());
stub.GenerateCall(masm_, ip);
// Drop the return address from the stack.
@@ -1094,7 +1071,7 @@ int RegExpMacroAssemblerARM::CheckStackGuardState(Address* return_address,
ASSERT(*return_address <=
re_code->instruction_start() + re_code->instruction_size());
- MaybeObject* result = Execution::HandleStackGuardInterrupt(isolate);
+ Object* result = Execution::HandleStackGuardInterrupt(isolate);
if (*code_handle != re_code) { // Return address no longer valid
int delta = code_handle->address() - re_code->address();
diff --git a/deps/v8/src/arm/regexp-macro-assembler-arm.h b/deps/v8/src/arm/regexp-macro-assembler-arm.h
index 8d9d515c76..4b18b274d7 100644
--- a/deps/v8/src/arm/regexp-macro-assembler-arm.h
+++ b/deps/v8/src/arm/regexp-macro-assembler-arm.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM_REGEXP_MACRO_ASSEMBLER_ARM_H_
#define V8_ARM_REGEXP_MACRO_ASSEMBLER_ARM_H_
diff --git a/deps/v8/src/arm/simulator-arm.cc b/deps/v8/src/arm/simulator-arm.cc
index 8f7c1e8bb2..80b46e04df 100644
--- a/deps/v8/src/arm/simulator-arm.cc
+++ b/deps/v8/src/arm/simulator-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <stdarg.h>
#include <stdlib.h>
@@ -773,8 +750,8 @@ Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
z_flag_FPSCR_ = false;
c_flag_FPSCR_ = false;
v_flag_FPSCR_ = false;
- FPSCR_rounding_mode_ = RZ;
- FPSCR_default_NaN_mode_ = true;
+ FPSCR_rounding_mode_ = RN;
+ FPSCR_default_NaN_mode_ = false;
inv_op_vfp_flag_ = false;
div_zero_vfp_flag_ = false;
@@ -2936,7 +2913,7 @@ void Simulator::DecodeTypeVFP(Instruction* instr) {
} else if ((instr->Opc2Value() == 0xA) && (instr->Opc3Value() == 0x3) &&
(instr->Bit(8) == 1)) {
// vcvt.f64.s32 Dd, Dd, #<fbits>
- int fraction_bits = 32 - ((instr->Bit(5) << 4) | instr->Bits(3, 0));
+ int fraction_bits = 32 - ((instr->Bits(3, 0) << 1) | instr->Bit(5));
int fixed_value = get_sinteger_from_s_register(vd * 2);
double divide = 1 << fraction_bits;
set_d_register_from_double(vd, fixed_value / divide);
diff --git a/deps/v8/src/arm/simulator-arm.h b/deps/v8/src/arm/simulator-arm.h
index 24d7fe58c4..bbe87bcbe2 100644
--- a/deps/v8/src/arm/simulator-arm.h
+++ b/deps/v8/src/arm/simulator-arm.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Declares a Simulator for ARM instructions if we are not generating a native
diff --git a/deps/v8/src/arm/stub-cache-arm.cc b/deps/v8/src/arm/stub-cache-arm.cc
index c595e42745..fd53b9782d 100644
--- a/deps/v8/src/arm/stub-cache-arm.cc
+++ b/deps/v8/src/arm/stub-cache-arm.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -431,6 +408,22 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
__ JumpIfSmi(value_reg, miss_label);
+ HeapType* field_type = descriptors->GetFieldType(descriptor);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ __ ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ while (true) {
+ __ CompareMap(scratch1, it.Current(), &do_store);
+ it.Advance();
+ if (it.Done()) {
+ __ b(ne, miss_label);
+ break;
+ }
+ __ b(eq, &do_store);
+ }
+ __ bind(&do_store);
+ }
} else if (representation.IsDouble()) {
Label do_store, heap_number;
__ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex);
@@ -593,6 +586,22 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
__ JumpIfSmi(value_reg, miss_label);
+ HeapType* field_type = lookup->GetFieldType();
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ __ ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ while (true) {
+ __ CompareMap(scratch1, it.Current(), &do_store);
+ it.Advance();
+ if (it.Done()) {
+ __ b(ne, miss_label);
+ break;
+ }
+ __ b(eq, &do_store);
+ }
+ __ bind(&do_store);
+ }
} else if (representation.IsDouble()) {
// Load the double storage.
if (index < 0) {
@@ -801,7 +810,7 @@ void StubCompiler::GenerateFastApiCall(MacroAssembler* masm,
__ mov(api_function_address, Operand(ref));
// Jump to stub.
- CallApiFunctionStub stub(is_store, call_data_undefined, argc);
+ CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
__ TailCallStub(&stub);
}
@@ -836,7 +845,9 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
int depth = 0;
Handle<JSObject> current = Handle<JSObject>::null();
- if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant());
+ if (type->IsConstant()) {
+ current = Handle<JSObject>::cast(type->AsConstant()->Value());
+ }
Handle<JSObject> prototype = Handle<JSObject>::null();
Handle<Map> current_map = receiver_map;
Handle<Map> holder_map(holder->map());
@@ -859,7 +870,7 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
name = factory()->InternalizeString(Handle<String>::cast(name));
}
ASSERT(current.is_null() ||
- current->property_dictionary()->FindEntry(*name) ==
+ current->property_dictionary()->FindEntry(name) ==
NameDictionary::kNotFound);
GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
@@ -999,15 +1010,17 @@ void LoadStubCompiler::GenerateLoadField(Register reg,
Representation representation) {
if (!reg.is(receiver())) __ mov(receiver(), reg);
if (kind() == Code::LOAD_IC) {
- LoadFieldStub stub(field.is_inobject(holder),
+ LoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
field.translate(holder),
representation);
- GenerateTailCall(masm(), stub.GetCode(isolate()));
+ GenerateTailCall(masm(), stub.GetCode());
} else {
- KeyedLoadFieldStub stub(field.is_inobject(holder),
+ KeyedLoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
field.translate(holder),
representation);
- GenerateTailCall(masm(), stub.GetCode(isolate()));
+ GenerateTailCall(masm(), stub.GetCode());
}
}
@@ -1061,7 +1074,7 @@ void LoadStubCompiler::GenerateLoadCallback(
ExternalReference ref = ExternalReference(&fun, type, isolate());
__ mov(getter_address_reg, Operand(ref));
- CallApiGetterStub stub;
+ CallApiGetterStub stub(isolate());
__ TailCallStub(&stub);
}
@@ -1154,19 +1167,6 @@ void LoadStubCompiler::GenerateLoadInterceptor(
}
-void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
- Label success;
- // Check that the object is a boolean.
- __ LoadRoot(ip, Heap::kTrueValueRootIndex);
- __ cmp(object, ip);
- __ b(eq, &success);
- __ LoadRoot(ip, Heap::kFalseValueRootIndex);
- __ cmp(object, ip);
- __ b(ne, miss);
- __ bind(&success);
-}
-
-
Handle<Code> StoreStubCompiler::CompileStoreCallback(
Handle<JSObject> object,
Handle<JSObject> holder,
diff --git a/deps/v8/src/arm64/assembler-arm64-inl.h b/deps/v8/src/arm64/assembler-arm64-inl.h
index b56e3ed2a1..3c17153f68 100644
--- a/deps/v8/src/arm64/assembler-arm64-inl.h
+++ b/deps/v8/src/arm64/assembler-arm64-inl.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_ASSEMBLER_ARM64_INL_H_
#define V8_ARM64_ASSEMBLER_ARM64_INL_H_
@@ -434,6 +411,12 @@ Operand Operand::UntagSmiAndScale(Register smi, int scale) {
}
+MemOperand::MemOperand()
+ : base_(NoReg), regoffset_(NoReg), offset_(0), addrmode_(Offset),
+ shift_(NO_SHIFT), extend_(NO_EXTEND), shift_amount_(0) {
+}
+
+
MemOperand::MemOperand(Register base, ptrdiff_t offset, AddrMode addrmode)
: base_(base), regoffset_(NoReg), offset_(offset), addrmode_(addrmode),
shift_(NO_SHIFT), extend_(NO_EXTEND), shift_amount_(0) {
@@ -738,7 +721,7 @@ void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode mode) {
}
-static const int kCodeAgeSequenceSize = 5 * kInstructionSize;
+static const int kNoCodeAgeSequenceLength = 5 * kInstructionSize;
static const int kCodeAgeStubEntryOffset = 3 * kInstructionSize;
@@ -750,7 +733,6 @@ Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) {
Code* RelocInfo::code_age_stub() {
ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
- ASSERT(!Code::IsYoungSequence(pc_));
// Read the stub entry point from the code age sequence.
Address stub_entry_address = pc_ + kCodeAgeStubEntryOffset;
return Code::GetCodeFromTargetAddress(Memory::Address_at(stub_entry_address));
@@ -759,7 +741,7 @@ Code* RelocInfo::code_age_stub() {
void RelocInfo::set_code_age_stub(Code* stub) {
ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
- ASSERT(!Code::IsYoungSequence(pc_));
+ ASSERT(!Code::IsYoungSequence(stub->GetIsolate(), pc_));
// Overwrite the stub entry point in the code age sequence. This is loaded as
// a literal so there is no need to call FlushICache here.
Address stub_entry_address = pc_ + kCodeAgeStubEntryOffset;
@@ -825,14 +807,12 @@ void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
visitor->VisitCell(this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(this);
-#ifdef ENABLE_DEBUGGER_SUPPORT
} else if (((RelocInfo::IsJSReturn(mode) &&
IsPatchedReturnSequence()) ||
(RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence())) &&
isolate->debug()->has_break_points()) {
visitor->VisitDebugTarget(this);
-#endif
} else if (RelocInfo::IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this);
}
@@ -850,14 +830,12 @@ void RelocInfo::Visit(Heap* heap) {
StaticVisitor::VisitCell(heap, this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
StaticVisitor::VisitExternalReference(this);
-#ifdef ENABLE_DEBUGGER_SUPPORT
} else if (heap->isolate()->debug()->has_break_points() &&
((RelocInfo::IsJSReturn(mode) &&
IsPatchedReturnSequence()) ||
(RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence()))) {
StaticVisitor::VisitDebugTarget(heap, this);
-#endif
} else if (RelocInfo::IsRuntimeEntry(mode)) {
StaticVisitor::VisitRuntimeEntry(this);
}
@@ -1199,11 +1177,16 @@ void Assembler::LoadRelocated(const CPURegister& rt, const Operand& operand) {
}
-inline void Assembler::CheckBuffer() {
+inline void Assembler::CheckBufferSpace() {
ASSERT(pc_ < (buffer_ + buffer_size_));
if (buffer_space() < kGap) {
GrowBuffer();
}
+}
+
+
+inline void Assembler::CheckBuffer() {
+ CheckBufferSpace();
if (pc_offset() >= next_veneer_pool_check_) {
CheckVeneerPool(false, true);
}
diff --git a/deps/v8/src/arm64/assembler-arm64.cc b/deps/v8/src/arm64/assembler-arm64.cc
index 8bee92ccc2..14f4145578 100644
--- a/deps/v8/src/arm64/assembler-arm64.cc
+++ b/deps/v8/src/arm64/assembler-arm64.cc
@@ -271,14 +271,9 @@ void Operand::initialize_handle(Handle<Object> handle) {
}
-bool Operand::NeedsRelocation() const {
+bool Operand::NeedsRelocation(Isolate* isolate) const {
if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) {
-#ifdef DEBUG
- if (!Serializer::enabled()) {
- Serializer::TooLateToEnableNow();
- }
-#endif
- return Serializer::enabled();
+ return Serializer::enabled(isolate);
}
return !RelocInfo::IsNone(rmode_);
@@ -456,6 +451,8 @@ void Assembler::bind(Label* label) {
ASSERT(!label->is_near_linked());
ASSERT(!label->is_bound());
+ DeleteUnresolvedBranchInfoForLabel(label);
+
// If the label is linked, the link chain looks something like this:
//
// |--I----I-------I-------L
@@ -497,8 +494,6 @@ void Assembler::bind(Label* label) {
ASSERT(label->is_bound());
ASSERT(!label->is_linked());
-
- DeleteUnresolvedBranchInfoForLabel(label);
}
@@ -545,21 +540,50 @@ int Assembler::LinkAndGetByteOffsetTo(Label* label) {
}
+void Assembler::DeleteUnresolvedBranchInfoForLabelTraverse(Label* label) {
+ ASSERT(label->is_linked());
+ CheckLabelLinkChain(label);
+
+ int link_offset = label->pos();
+ int link_pcoffset;
+ bool end_of_chain = false;
+
+ while (!end_of_chain) {
+ Instruction * link = InstructionAt(link_offset);
+ link_pcoffset = link->ImmPCOffset();
+
+ // ADR instructions are not handled by veneers.
+ if (link->IsImmBranch()) {
+ int max_reachable_pc = InstructionOffset(link) +
+ Instruction::ImmBranchRange(link->BranchType());
+ typedef std::multimap<int, FarBranchInfo>::iterator unresolved_info_it;
+ std::pair<unresolved_info_it, unresolved_info_it> range;
+ range = unresolved_branches_.equal_range(max_reachable_pc);
+ unresolved_info_it it;
+ for (it = range.first; it != range.second; ++it) {
+ if (it->second.pc_offset_ == link_offset) {
+ unresolved_branches_.erase(it);
+ break;
+ }
+ }
+ }
+
+ end_of_chain = (link_pcoffset == 0);
+ link_offset = link_offset + link_pcoffset;
+ }
+}
+
+
void Assembler::DeleteUnresolvedBranchInfoForLabel(Label* label) {
if (unresolved_branches_.empty()) {
ASSERT(next_veneer_pool_check_ == kMaxInt);
return;
}
- // Branches to this label will be resolved when the label is bound below.
- std::multimap<int, FarBranchInfo>::iterator it_tmp, it;
- it = unresolved_branches_.begin();
- while (it != unresolved_branches_.end()) {
- it_tmp = it++;
- if (it_tmp->second.label_ == label) {
- CHECK(it_tmp->first >= pc_offset());
- unresolved_branches_.erase(it_tmp);
- }
+ if (label->is_linked()) {
+ // Branches to this label will be resolved when the label is bound, normally
+ // just after all the associated info has been deleted.
+ DeleteUnresolvedBranchInfoForLabelTraverse(label);
}
if (unresolved_branches_.empty()) {
next_veneer_pool_check_ = kMaxInt;
@@ -645,7 +669,7 @@ int Assembler::ConstantPoolSizeAt(Instruction* instr) {
void Assembler::ConstantPoolMarker(uint32_t size) {
ASSERT(is_const_pool_blocked());
// + 1 is for the crash guard.
- Emit(LDR_x_lit | ImmLLiteral(2 * size + 1) | Rt(xzr));
+ Emit(LDR_x_lit | ImmLLiteral(size + 1) | Rt(xzr));
}
@@ -1658,6 +1682,13 @@ void Assembler::frinta(const FPRegister& fd,
}
+void Assembler::frintm(const FPRegister& fd,
+ const FPRegister& fn) {
+ ASSERT(fd.SizeInBits() == fn.SizeInBits());
+ FPDataProcessing1Source(fd, fn, FRINTM);
+}
+
+
void Assembler::frintn(const FPRegister& fd,
const FPRegister& fn) {
ASSERT(fd.SizeInBits() == fn.SizeInBits());
@@ -1872,7 +1903,7 @@ void Assembler::AddSub(const Register& rd,
FlagsUpdate S,
AddSubOp op) {
ASSERT(rd.SizeInBits() == rn.SizeInBits());
- ASSERT(!operand.NeedsRelocation());
+ ASSERT(!operand.NeedsRelocation(isolate()));
if (operand.IsImmediate()) {
int64_t immediate = operand.immediate();
ASSERT(IsImmAddSub(immediate));
@@ -1912,7 +1943,7 @@ void Assembler::AddSubWithCarry(const Register& rd,
ASSERT(rd.SizeInBits() == rn.SizeInBits());
ASSERT(rd.SizeInBits() == operand.reg().SizeInBits());
ASSERT(operand.IsShiftedRegister() && (operand.shift_amount() == 0));
- ASSERT(!operand.NeedsRelocation());
+ ASSERT(!operand.NeedsRelocation(isolate()));
Emit(SF(rd) | op | Flags(S) | Rm(operand.reg()) | Rn(rn) | Rd(rd));
}
@@ -1933,10 +1964,7 @@ void Assembler::debug(const char* message, uint32_t code, Instr params) {
#ifdef USE_SIMULATOR
// Don't generate simulator specific code if we are building a snapshot, which
// might be run on real hardware.
- if (!Serializer::enabled()) {
-#ifdef DEBUG
- Serializer::TooLateToEnableNow();
-#endif
+ if (!Serializer::enabled(isolate())) {
// The arguments to the debug marker need to be contiguous in memory, so
// make sure we don't try to emit pools.
BlockPoolsScope scope(this);
@@ -1971,7 +1999,7 @@ void Assembler::Logical(const Register& rd,
const Operand& operand,
LogicalOp op) {
ASSERT(rd.SizeInBits() == rn.SizeInBits());
- ASSERT(!operand.NeedsRelocation());
+ ASSERT(!operand.NeedsRelocation(isolate()));
if (operand.IsImmediate()) {
int64_t immediate = operand.immediate();
unsigned reg_size = rd.SizeInBits();
@@ -2023,7 +2051,7 @@ void Assembler::ConditionalCompare(const Register& rn,
Condition cond,
ConditionalCompareOp op) {
Instr ccmpop;
- ASSERT(!operand.NeedsRelocation());
+ ASSERT(!operand.NeedsRelocation(isolate()));
if (operand.IsImmediate()) {
int64_t immediate = operand.immediate();
ASSERT(IsImmConditionalCompare(immediate));
@@ -2138,7 +2166,7 @@ void Assembler::DataProcShiftedRegister(const Register& rd,
Instr op) {
ASSERT(operand.IsShiftedRegister());
ASSERT(rn.Is64Bits() || (rn.Is32Bits() && is_uint5(operand.shift_amount())));
- ASSERT(!operand.NeedsRelocation());
+ ASSERT(!operand.NeedsRelocation(isolate()));
Emit(SF(rd) | op | Flags(S) |
ShiftDP(operand.shift()) | ImmDPShift(operand.shift_amount()) |
Rm(operand.reg()) | Rn(rn) | Rd(rd));
@@ -2150,7 +2178,7 @@ void Assembler::DataProcExtendedRegister(const Register& rd,
const Operand& operand,
FlagsUpdate S,
Instr op) {
- ASSERT(!operand.NeedsRelocation());
+ ASSERT(!operand.NeedsRelocation(isolate()));
Instr dest_reg = (S == SetFlags) ? Rd(rd) : RdSP(rd);
Emit(SF(rd) | op | Flags(S) | Rm(operand.reg()) |
ExtendMode(operand.extend()) | ImmExtendShift(operand.shift_amount()) |
@@ -2489,12 +2517,7 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
if (!RelocInfo::IsNone(rmode)) {
// Don't record external references unless the heap will be serialized.
if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
-#ifdef DEBUG
- if (!Serializer::enabled()) {
- Serializer::TooLateToEnableNow();
- }
-#endif
- if (!Serializer::enabled() && !emit_debug_code()) {
+ if (!Serializer::enabled(isolate()) && !emit_debug_code()) {
return;
}
}
@@ -2581,7 +2604,6 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
{
// Block recursive calls to CheckConstPool and protect from veneer pools.
BlockPoolsScope block_pools(this);
- RecordComment("[ Constant Pool");
RecordConstPool(pool_size);
// Emit jump over constant pool if necessary.
@@ -2601,6 +2623,7 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
// beginning of the constant pool.
// TODO(all): currently each relocated constant is 64 bits, consider adding
// support for 32-bit entries.
+ RecordComment("[ Constant Pool");
ConstantPoolMarker(2 * num_pending_reloc_info_);
ConstantPoolGuard();
@@ -2650,12 +2673,10 @@ bool Assembler::ShouldEmitVeneer(int max_reachable_pc, int margin) {
void Assembler::RecordVeneerPool(int location_offset, int size) {
-#ifdef ENABLE_DEBUGGER_SUPPORT
RelocInfo rinfo(buffer_ + location_offset,
RelocInfo::VENEER_POOL, static_cast<intptr_t>(size),
NULL);
reloc_info_writer.Write(&rinfo);
-#endif
}
@@ -2789,22 +2810,91 @@ void Assembler::RecordDebugBreakSlot() {
void Assembler::RecordConstPool(int size) {
// We only need this for debugger support, to correctly compute offsets in the
// code.
-#ifdef ENABLE_DEBUGGER_SUPPORT
RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size));
-#endif
}
-MaybeObject* Assembler::AllocateConstantPool(Heap* heap) {
+Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
// No out-of-line constant pool support.
- UNREACHABLE();
- return NULL;
+ ASSERT(!FLAG_enable_ool_constant_pool);
+ return isolate->factory()->empty_constant_pool_array();
}
void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
// No out-of-line constant pool support.
- UNREACHABLE();
+ ASSERT(!FLAG_enable_ool_constant_pool);
+ return;
+}
+
+
+void PatchingAssembler::MovInt64(const Register& rd, int64_t imm) {
+ Label start;
+ bind(&start);
+
+ ASSERT(rd.Is64Bits());
+ ASSERT(!rd.IsSP());
+
+ for (unsigned i = 0; i < (rd.SizeInBits() / 16); i++) {
+ uint64_t imm16 = (imm >> (16 * i)) & 0xffffL;
+ movk(rd, imm16, 16 * i);
+ }
+
+ ASSERT(SizeOfCodeGeneratedSince(&start) ==
+ kMovInt64NInstrs * kInstructionSize);
+}
+
+
+void PatchingAssembler::PatchAdrFar(Instruction* target) {
+ // The code at the current instruction should be:
+ // adr rd, 0
+ // nop (adr_far)
+ // nop (adr_far)
+ // nop (adr_far)
+ // movz scratch, 0
+ // add rd, rd, scratch
+
+ // Verify the expected code.
+ Instruction* expected_adr = InstructionAt(0);
+ CHECK(expected_adr->IsAdr() && (expected_adr->ImmPCRel() == 0));
+ int rd_code = expected_adr->Rd();
+ for (int i = 0; i < kAdrFarPatchableNNops; ++i) {
+ CHECK(InstructionAt((i + 1) * kInstructionSize)->IsNop(ADR_FAR_NOP));
+ }
+ Instruction* expected_movz =
+ InstructionAt((kAdrFarPatchableNInstrs - 2) * kInstructionSize);
+ CHECK(expected_movz->IsMovz() &&
+ (expected_movz->ImmMoveWide() == 0) &&
+ (expected_movz->ShiftMoveWide() == 0));
+ int scratch_code = expected_movz->Rd();
+ Instruction* expected_add =
+ InstructionAt((kAdrFarPatchableNInstrs - 1) * kInstructionSize);
+ CHECK(expected_add->IsAddSubShifted() &&
+ (expected_add->Mask(AddSubOpMask) == ADD) &&
+ expected_add->SixtyFourBits() &&
+ (expected_add->Rd() == rd_code) && (expected_add->Rn() == rd_code) &&
+ (expected_add->Rm() == scratch_code) &&
+ (static_cast<Shift>(expected_add->ShiftDP()) == LSL) &&
+ (expected_add->ImmDPShift() == 0));
+
+ // Patch to load the correct address.
+ Label start;
+ bind(&start);
+ Register rd = Register::XRegFromCode(rd_code);
+ // If the target is in range, we only patch the adr. Otherwise we patch the
+ // nops with fixup instructions.
+ int target_offset = expected_adr->DistanceTo(target);
+ if (Instruction::IsValidPCRelOffset(target_offset)) {
+ adr(rd, target_offset);
+ for (int i = 0; i < kAdrFarPatchableNInstrs - 2; ++i) {
+ nop(ADR_FAR_NOP);
+ }
+ } else {
+ Register scratch = Register::XRegFromCode(scratch_code);
+ adr(rd, 0);
+ MovInt64(scratch, target_offset);
+ add(rd, rd, scratch);
+ }
}
diff --git a/deps/v8/src/arm64/assembler-arm64.h b/deps/v8/src/arm64/assembler-arm64.h
index 1aae2f291e..a3fbc98d97 100644
--- a/deps/v8/src/arm64/assembler-arm64.h
+++ b/deps/v8/src/arm64/assembler-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_ASSEMBLER_ARM64_H_
#define V8_ARM64_ASSEMBLER_ARM64_H_
@@ -285,9 +262,9 @@ struct FPRegister : public CPURegister {
static const unsigned kAllocatableLowRangeBegin = 0;
static const unsigned kAllocatableLowRangeEnd = 14;
static const unsigned kAllocatableHighRangeBegin = 16;
- static const unsigned kAllocatableHighRangeEnd = 29;
+ static const unsigned kAllocatableHighRangeEnd = 28;
- static const RegList kAllocatableFPRegisters = 0x3fff7fff;
+ static const RegList kAllocatableFPRegisters = 0x1fff7fff;
// Gap between low and high ranges.
static const int kAllocatableRangeGapSize =
@@ -316,12 +293,12 @@ struct FPRegister : public CPURegister {
ASSERT((kAllocatableLowRangeBegin == 0) &&
(kAllocatableLowRangeEnd == 14) &&
(kAllocatableHighRangeBegin == 16) &&
- (kAllocatableHighRangeEnd == 29));
+ (kAllocatableHighRangeEnd == 28));
const char* const names[] = {
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
"d8", "d9", "d10", "d11", "d12", "d13", "d14",
"d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
- "d24", "d25", "d26", "d27", "d28", "d29"
+ "d24", "d25", "d26", "d27", "d28"
};
return names[index];
}
@@ -420,9 +397,11 @@ ALIAS_REGISTER(Register, wzr, w31);
// Keeps the 0 double value.
ALIAS_REGISTER(FPRegister, fp_zero, d15);
// Crankshaft double scratch register.
-ALIAS_REGISTER(FPRegister, crankshaft_fp_scratch, d30);
-// MacroAssembler double scratch register.
-ALIAS_REGISTER(FPRegister, fp_scratch, d31);
+ALIAS_REGISTER(FPRegister, crankshaft_fp_scratch, d29);
+// MacroAssembler double scratch registers.
+ALIAS_REGISTER(FPRegister, fp_scratch, d30);
+ALIAS_REGISTER(FPRegister, fp_scratch1, d30);
+ALIAS_REGISTER(FPRegister, fp_scratch2, d31);
#undef ALIAS_REGISTER
@@ -514,8 +493,8 @@ class CPURegList {
void Combine(const CPURegList& other);
// Remove every register in the other CPURegList from this one. Registers that
- // do not exist in this list are ignored. The type and size of the registers
- // in the 'other' list must match those in this list.
+ // do not exist in this list are ignored. The type of the registers in the
+ // 'other' list must match those in this list.
void Remove(const CPURegList& other);
// Variants of Combine and Remove which take CPURegisters.
@@ -670,7 +649,7 @@ class Operand {
// Relocation information.
RelocInfo::Mode rmode() const { return rmode_; }
void set_rmode(RelocInfo::Mode rmode) { rmode_ = rmode; }
- bool NeedsRelocation() const;
+ bool NeedsRelocation(Isolate* isolate) const;
// Helpers
inline static Operand UntagSmi(Register smi);
@@ -690,6 +669,7 @@ class Operand {
// MemOperand represents a memory operand in a load or store instruction.
class MemOperand {
public:
+ inline explicit MemOperand();
inline explicit MemOperand(Register base,
ptrdiff_t offset = 0,
AddrMode addrmode = Offset);
@@ -1499,8 +1479,9 @@ class Assembler : public AssemblerBase {
enum NopMarkerTypes {
DEBUG_BREAK_NOP,
INTERRUPT_CODE_NOP,
+ ADR_FAR_NOP,
FIRST_NOP_MARKER = DEBUG_BREAK_NOP,
- LAST_NOP_MARKER = INTERRUPT_CODE_NOP
+ LAST_NOP_MARKER = ADR_FAR_NOP
};
void nop(NopMarkerTypes n) {
@@ -1582,6 +1563,9 @@ class Assembler : public AssemblerBase {
// FP round to integer (nearest with ties to away).
void frinta(const FPRegister& fd, const FPRegister& fn);
+ // FP round to integer (toward minus infinity).
+ void frintm(const FPRegister& fd, const FPRegister& fn);
+
// FP round to integer (nearest with ties to even).
void frintn(const FPRegister& fd, const FPRegister& fn);
@@ -1688,6 +1672,10 @@ class Assembler : public AssemblerBase {
return reinterpret_cast<Instruction*>(buffer_ + offset);
}
+ ptrdiff_t InstructionOffset(Instruction* instr) const {
+ return reinterpret_cast<byte*>(instr) - buffer_;
+ }
+
// Register encoding.
static Instr Rd(CPURegister rd) {
ASSERT(rd.code() != kSPRegInternalCode);
@@ -1761,6 +1749,13 @@ class Assembler : public AssemblerBase {
inline static Instr ImmCondCmp(unsigned imm);
inline static Instr Nzcv(StatusFlags nzcv);
+ static bool IsImmAddSub(int64_t immediate);
+ static bool IsImmLogical(uint64_t value,
+ unsigned width,
+ unsigned* n,
+ unsigned* imm_s,
+ unsigned* imm_r);
+
// MemOperand offset encoding.
inline static Instr ImmLSUnsigned(int imm12);
inline static Instr ImmLS(int imm9);
@@ -1805,7 +1800,7 @@ class Assembler : public AssemblerBase {
void CheckConstPool(bool force_emit, bool require_jump);
// Allocate a constant pool of the correct size for the generated code.
- MaybeObject* AllocateConstantPool(Heap* heap);
+ Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate);
// Generate the constant pool for the generated code.
void PopulateConstantPool(ConstantPoolArray* constant_pool);
@@ -1874,11 +1869,6 @@ class Assembler : public AssemblerBase {
unsigned imm_s,
unsigned imm_r,
LogicalOp op);
- static bool IsImmLogical(uint64_t value,
- unsigned width,
- unsigned* n,
- unsigned* imm_s,
- unsigned* imm_r);
void ConditionalCompare(const Register& rn,
const Operand& operand,
@@ -1909,7 +1899,6 @@ class Assembler : public AssemblerBase {
const Operand& operand,
FlagsUpdate S,
AddSubOp op);
- static bool IsImmAddSub(int64_t immediate);
static bool IsImmFP32(float imm);
static bool IsImmFP64(double imm);
@@ -2034,6 +2023,7 @@ class Assembler : public AssemblerBase {
}
void GrowBuffer();
+ void CheckBufferSpace();
void CheckBuffer();
// Pc offset of the next constant pool check.
@@ -2176,6 +2166,11 @@ class Assembler : public AssemblerBase {
// not later attempt (likely unsuccessfully) to patch it to branch directly to
// the label.
void DeleteUnresolvedBranchInfoForLabel(Label* label);
+ // This function deletes the information related to the label by traversing
+ // the label chain, and for each PC-relative instruction in the chain checking
+ // if pending unresolved information exists. Its complexity is proportional to
+ // the length of the label chain.
+ void DeleteUnresolvedBranchInfoForLabelTraverse(Label* label);
private:
PositionsRecorder positions_recorder_;
@@ -2218,13 +2213,21 @@ class PatchingAssembler : public Assembler {
size_t length = buffer_size_ - kGap;
CPU::FlushICache(buffer_, length);
}
+
+ static const int kMovInt64NInstrs = 4;
+ void MovInt64(const Register& rd, int64_t imm);
+
+ // See definition of PatchAdrFar() for details.
+ static const int kAdrFarPatchableNNops = kMovInt64NInstrs - 1;
+ static const int kAdrFarPatchableNInstrs = kAdrFarPatchableNNops + 3;
+ void PatchAdrFar(Instruction* target);
};
class EnsureSpace BASE_EMBEDDED {
public:
explicit EnsureSpace(Assembler* assembler) {
- assembler->CheckBuffer();
+ assembler->CheckBufferSpace();
}
};
diff --git a/deps/v8/src/arm64/builtins-arm64.cc b/deps/v8/src/arm64/builtins-arm64.cc
index 01ac4cc5db..fec5fef99a 100644
--- a/deps/v8/src/arm64/builtins-arm64.cc
+++ b/deps/v8/src/arm64/builtins-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -370,13 +347,11 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
Label rt_call, allocated;
if (FLAG_inline_new) {
Label undo_allocation;
-#if ENABLE_DEBUGGER_SUPPORT
ExternalReference debug_step_in_fp =
ExternalReference::debug_step_in_fp_address(isolate);
__ Mov(x2, Operand(debug_step_in_fp));
__ Ldr(x2, MemOperand(x2));
__ Cbnz(x2, &rt_call);
-#endif
// Load the initial map and verify that it is in fact a map.
Register init_map = x2;
__ Ldr(init_map,
@@ -785,7 +760,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
// No type feedback cell is available.
__ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
- CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
+ CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
ParameterCount actual(x0);
@@ -912,7 +887,7 @@ void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
}
// Jump to point after the code-age stub.
- __ Add(x0, x0, kCodeAgeSequenceSize);
+ __ Add(x0, x0, kNoCodeAgeSequenceLength);
__ Br(x0);
}
@@ -1280,7 +1255,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// There is not enough stack space, so use a builtin to throw an appropriate
// error.
__ Push(function, argc);
- __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
+ __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
// We should never return from the APPLY_OVERFLOW builtin.
if (__ emit_debug_code()) {
__ Unreachable();
@@ -1400,6 +1375,27 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
}
+static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
+ Label* stack_overflow) {
+ // ----------- S t a t e -------------
+ // -- x0 : actual number of arguments
+ // -- x1 : function (passed through to callee)
+ // -- x2 : expected number of arguments
+ // -----------------------------------
+ // Check the stack for overflow.
+ // We are not trying to catch interruptions (e.g. debug break and
+ // preemption) here, so the "real stack limit" is checked.
+ Label enough_stack_space;
+ __ LoadRoot(x10, Heap::kRealStackLimitRootIndex);
+ // Make x10 the space we have left. The stack might already be overflowed
+ // here which will cause x10 to become negative.
+ __ Sub(x10, jssp, x10);
+ // Check if the arguments will overflow the stack.
+ __ Cmp(x10, Operand(x2, LSL, kPointerSizeLog2));
+ __ B(le, stack_overflow);
+}
+
+
static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
__ SmiTag(x10, x0);
__ Mov(x11, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
@@ -1433,6 +1429,9 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// -- x2 : expected number of arguments
// -----------------------------------
+ Label stack_overflow;
+ ArgumentAdaptorStackCheck(masm, &stack_overflow);
+
Register argc_actual = x0; // Excluding the receiver.
Register argc_expected = x2; // Excluding the receiver.
Register function = x1;
@@ -1552,6 +1551,14 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// Call the entry point without adapting the arguments.
__ Bind(&dont_adapt_arguments);
__ Jump(code_entry);
+
+ __ Bind(&stack_overflow);
+ {
+ FrameScope frame(masm, StackFrame::MANUAL);
+ EnterArgumentsAdaptorFrame(masm);
+ __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
+ __ Unreachable();
+ }
}
diff --git a/deps/v8/src/arm64/code-stubs-arm64.cc b/deps/v8/src/arm64/code-stubs-arm64.cc
index b097fc52ed..a2dd220586 100644
--- a/deps/v8/src/arm64/code-stubs-arm64.cc
+++ b/deps/v8/src/arm64/code-stubs-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -39,7 +16,6 @@ namespace internal {
void FastNewClosureStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x2: function info
static Register registers[] = { x2 };
@@ -51,7 +27,6 @@ void FastNewClosureStub::InitializeInterfaceDescriptor(
void FastNewContextStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x1: function
static Register registers[] = { x1 };
@@ -62,7 +37,6 @@ void FastNewContextStub::InitializeInterfaceDescriptor(
void ToNumberStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x0: value
static Register registers[] = { x0 };
@@ -73,7 +47,6 @@ void ToNumberStub::InitializeInterfaceDescriptor(
void NumberToStringStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x0: value
static Register registers[] = { x0 };
@@ -85,7 +58,6 @@ void NumberToStringStub::InitializeInterfaceDescriptor(
void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x3: array literals array
// x2: array literal index
@@ -100,7 +72,6 @@ void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x3: object literals array
// x2: object literal index
@@ -115,7 +86,6 @@ void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x2: feedback vector
// x3: call feedback slot
@@ -127,7 +97,6 @@ void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x1: receiver
// x0: key
@@ -140,7 +109,6 @@ void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x1: receiver
// x0: key
@@ -153,7 +121,6 @@ void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
void RegExpConstructResultStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x2: length
// x1: index (of last match)
@@ -167,7 +134,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor(
void LoadFieldStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x0: receiver
static Register registers[] = { x0 };
@@ -178,7 +144,6 @@ void LoadFieldStub::InitializeInterfaceDescriptor(
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x1: receiver
static Register registers[] = { x1 };
@@ -189,7 +154,6 @@ void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
void StringLengthStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { x0, x2 };
descriptor->register_param_count_ = 2;
@@ -199,7 +163,6 @@ void StringLengthStub::InitializeInterfaceDescriptor(
void KeyedStringLengthStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { x1, x0 };
descriptor->register_param_count_ = 2;
@@ -209,7 +172,6 @@ void KeyedStringLengthStub::InitializeInterfaceDescriptor(
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x2: receiver
// x1: key
@@ -223,7 +185,6 @@ void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
void TransitionElementsKindStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x0: value (js_array)
// x1: to_map
@@ -237,7 +198,6 @@ void TransitionElementsKindStub::InitializeInterfaceDescriptor(
void CompareNilICStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x0: value to compare
static Register registers[] = { x0 };
@@ -246,12 +206,11 @@ void CompareNilICStub::InitializeInterfaceDescriptor(
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(CompareNilIC_Miss);
descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate));
+ ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate()));
}
static void InitializeArrayConstructorDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor,
int constant_stack_parameter_count) {
// x1: function
@@ -281,28 +240,24 @@ static void InitializeArrayConstructorDescriptor(
void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(isolate, descriptor, 0);
+ InitializeArrayConstructorDescriptor(descriptor, 0);
}
void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(isolate, descriptor, 1);
+ InitializeArrayConstructorDescriptor(descriptor, 1);
}
void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(isolate, descriptor, -1);
+ InitializeArrayConstructorDescriptor(descriptor, -1);
}
static void InitializeInternalArrayConstructorDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor,
int constant_stack_parameter_count) {
// x1: constructor function
@@ -331,28 +286,24 @@ static void InitializeInternalArrayConstructorDescriptor(
void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 0);
+ InitializeInternalArrayConstructorDescriptor(descriptor, 0);
}
void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 1);
+ InitializeInternalArrayConstructorDescriptor(descriptor, 1);
}
void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(isolate, descriptor, -1);
+ InitializeInternalArrayConstructorDescriptor(descriptor, -1);
}
void ToBooleanStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x0: value
static Register registers[] = { x0 };
@@ -360,12 +311,11 @@ void ToBooleanStub::InitializeInterfaceDescriptor(
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = FUNCTION_ADDR(ToBooleanIC_Miss);
descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate));
+ ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate()));
}
void StoreGlobalStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x1: receiver
// x2: key (unused)
@@ -379,7 +329,6 @@ void StoreGlobalStub::InitializeInterfaceDescriptor(
void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x0: value
// x3: target map
@@ -394,7 +343,6 @@ void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
void BinaryOpICStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x1: left operand
// x0: right operand
@@ -403,12 +351,11 @@ void BinaryOpICStub::InitializeInterfaceDescriptor(
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate));
+ ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate()));
}
void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x2: allocation site
// x1: left operand
@@ -422,7 +369,6 @@ void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
void StringAddStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
// x1: left operand
// x0: right operand
@@ -534,10 +480,9 @@ void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
// Update the static counter each time a new code stub is generated.
- Isolate* isolate = masm->isolate();
- isolate->counters()->code_stubs()->Increment();
+ isolate()->counters()->code_stubs()->Increment();
- CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate);
+ CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor();
int param_count = descriptor->register_param_count_;
{
// Call the runtime system in a fresh internal frame.
@@ -1049,8 +994,7 @@ void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
__ JumpIfBothInstanceTypesAreNotSequentialAscii(lhs_type, rhs_type, x14,
x15, &slow);
- Isolate* isolate = masm->isolate();
- __ IncrementCounter(isolate->counters()->string_compare_native(), 1, x10,
+ __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, x10,
x11);
if (cond == eq) {
StringCompareStub::GenerateFlatAsciiStringEquals(masm, lhs, rhs,
@@ -1095,30 +1039,29 @@ void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
- // Preserve caller-saved registers x0-x7 and x10-x15. We don't care if x8, x9,
- // ip0 and ip1 are corrupted by the call into C.
CPURegList saved_regs = kCallerSaved;
- saved_regs.Remove(ip0);
- saved_regs.Remove(ip1);
- saved_regs.Remove(x8);
- saved_regs.Remove(x9);
+ CPURegList saved_fp_regs = kCallerSavedFP;
// We don't allow a GC during a store buffer overflow so there is no need to
// store the registers in any particular way, but we do have to store and
// restore them.
+
+ // We don't care if MacroAssembler scratch registers are corrupted.
+ saved_regs.Remove(*(masm->TmpList()));
+ saved_fp_regs.Remove(*(masm->FPTmpList()));
+
__ PushCPURegList(saved_regs);
if (save_doubles_ == kSaveFPRegs) {
- __ PushCPURegList(kCallerSavedFP);
+ __ PushCPURegList(saved_fp_regs);
}
AllowExternalCallThatCantCauseGC scope(masm);
- __ Mov(x0, ExternalReference::isolate_address(masm->isolate()));
+ __ Mov(x0, ExternalReference::isolate_address(isolate()));
__ CallCFunction(
- ExternalReference::store_buffer_overflow_function(masm->isolate()),
- 1, 0);
+ ExternalReference::store_buffer_overflow_function(isolate()), 1, 0);
if (save_doubles_ == kSaveFPRegs) {
- __ PopCPURegList(kCallerSavedFP);
+ __ PopCPURegList(saved_fp_regs);
}
__ PopCPURegList(saved_regs);
__ Ret();
@@ -1127,10 +1070,10 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
Isolate* isolate) {
- StoreBufferOverflowStub stub1(kDontSaveFPRegs);
- stub1.GetCode(isolate);
- StoreBufferOverflowStub stub2(kSaveFPRegs);
- stub2.GetCode(isolate);
+ StoreBufferOverflowStub stub1(isolate, kDontSaveFPRegs);
+ stub1.GetCode();
+ StoreBufferOverflowStub stub2(isolate, kSaveFPRegs);
+ stub2.GetCode();
}
@@ -1230,8 +1173,8 @@ void MathPowStub::Generate(MacroAssembler* masm) {
if (exponent_type_ != INTEGER) {
// Detect integer exponents stored as doubles and handle those in the
// integer fast-path.
- __ TryConvertDoubleToInt64(exponent_integer, exponent_double,
- scratch0_double, &exponent_is_integer);
+ __ TryRepresentDoubleAsInt64(exponent_integer, exponent_double,
+ scratch0_double, &exponent_is_integer);
if (exponent_type_ == ON_STACK) {
FPRegister half_double = d3;
@@ -1314,7 +1257,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
AllowExternalCallThatCantCauseGC scope(masm);
__ Mov(saved_lr, lr);
__ CallCFunction(
- ExternalReference::power_double_double_function(masm->isolate()),
+ ExternalReference::power_double_double_function(isolate()),
0, 2);
__ Mov(lr, saved_lr);
__ B(&done);
@@ -1389,16 +1332,15 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ Bind(&call_runtime);
// Put the arguments back on the stack.
__ Push(base_tagged, exponent_tagged);
- __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
+ __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1);
// Return.
__ Bind(&done);
- __ AllocateHeapNumber(result_tagged, &call_runtime, scratch0, scratch1);
- __ Str(result_double,
- FieldMemOperand(result_tagged, HeapNumber::kValueOffset));
+ __ AllocateHeapNumber(result_tagged, &call_runtime, scratch0, scratch1,
+ result_double);
ASSERT(result_tagged.is(x0));
__ IncrementCounter(
- masm->isolate()->counters()->math_pow(), 1, scratch0, scratch1);
+ isolate()->counters()->math_pow(), 1, scratch0, scratch1);
__ Ret();
} else {
AllowExternalCallThatCantCauseGC scope(masm);
@@ -1406,12 +1348,12 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ Fmov(base_double, base_double_copy);
__ Scvtf(exponent_double, exponent_integer);
__ CallCFunction(
- ExternalReference::power_double_double_function(masm->isolate()),
+ ExternalReference::power_double_double_function(isolate()),
0, 2);
__ Mov(lr, saved_lr);
__ Bind(&done);
__ IncrementCounter(
- masm->isolate()->counters()->math_pow(), 1, scratch0, scratch1);
+ isolate()->counters()->math_pow(), 1, scratch0, scratch1);
__ Ret();
}
}
@@ -1435,18 +1377,18 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
void StoreRegistersStateStub::GenerateAheadOfTime(Isolate* isolate) {
- StoreRegistersStateStub stub1(kDontSaveFPRegs);
- stub1.GetCode(isolate);
- StoreRegistersStateStub stub2(kSaveFPRegs);
- stub2.GetCode(isolate);
+ StoreRegistersStateStub stub1(isolate, kDontSaveFPRegs);
+ stub1.GetCode();
+ StoreRegistersStateStub stub2(isolate, kSaveFPRegs);
+ stub2.GetCode();
}
void RestoreRegistersStateStub::GenerateAheadOfTime(Isolate* isolate) {
- RestoreRegistersStateStub stub1(kDontSaveFPRegs);
- stub1.GetCode(isolate);
- RestoreRegistersStateStub stub2(kSaveFPRegs);
- stub2.GetCode(isolate);
+ RestoreRegistersStateStub stub1(isolate, kDontSaveFPRegs);
+ stub1.GetCode();
+ RestoreRegistersStateStub stub2(isolate, kSaveFPRegs);
+ stub2.GetCode();
}
@@ -1471,22 +1413,85 @@ bool CEntryStub::NeedsImmovableCode() {
void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
- CEntryStub stub(1, kDontSaveFPRegs);
- stub.GetCode(isolate);
- CEntryStub stub_fp(1, kSaveFPRegs);
- stub_fp.GetCode(isolate);
+ CEntryStub stub(isolate, 1, kDontSaveFPRegs);
+ stub.GetCode();
+ CEntryStub stub_fp(isolate, 1, kSaveFPRegs);
+ stub_fp.GetCode();
}
-void CEntryStub::GenerateCore(MacroAssembler* masm,
- Label* throw_normal,
- Label* throw_termination,
- bool do_gc,
- bool always_allocate) {
- // x0 : Result parameter for PerformGC, if do_gc is true.
+void CEntryStub::Generate(MacroAssembler* masm) {
+ // The Abort mechanism relies on CallRuntime, which in turn relies on
+ // CEntryStub, so until this stub has been generated, we have to use a
+ // fall-back Abort mechanism.
+ //
+ // Note that this stub must be generated before any use of Abort.
+ MacroAssembler::NoUseRealAbortsScope no_use_real_aborts(masm);
+
+ ASM_LOCATION("CEntryStub::Generate entry");
+ ProfileEntryHookStub::MaybeCallEntryHook(masm);
+
+ // Register parameters:
+ // x0: argc (including receiver, untagged)
+ // x1: target
+ //
+ // The stack on entry holds the arguments and the receiver, with the receiver
+ // at the highest address:
+ //
+ // jssp]argc-1]: receiver
+ // jssp[argc-2]: arg[argc-2]
+ // ... ...
+ // jssp[1]: arg[1]
+ // jssp[0]: arg[0]
+ //
+ // The arguments are in reverse order, so that arg[argc-2] is actually the
+ // first argument to the target function and arg[0] is the last.
+ ASSERT(jssp.Is(__ StackPointer()));
+ const Register& argc_input = x0;
+ const Register& target_input = x1;
+
+ // Calculate argv, argc and the target address, and store them in
+ // callee-saved registers so we can retry the call without having to reload
+ // these arguments.
+ // TODO(jbramley): If the first call attempt succeeds in the common case (as
+ // it should), then we might be better off putting these parameters directly
+ // into their argument registers, rather than using callee-saved registers and
+ // preserving them on the stack.
+ const Register& argv = x21;
+ const Register& argc = x22;
+ const Register& target = x23;
+
+ // Derive argv from the stack pointer so that it points to the first argument
+ // (arg[argc-2]), or just below the receiver in case there are no arguments.
+ // - Adjust for the arg[] array.
+ Register temp_argv = x11;
+ __ Add(temp_argv, jssp, Operand(x0, LSL, kPointerSizeLog2));
+ // - Adjust for the receiver.
+ __ Sub(temp_argv, temp_argv, 1 * kPointerSize);
+
+ // Enter the exit frame. Reserve three slots to preserve x21-x23 callee-saved
+ // registers.
+ FrameScope scope(masm, StackFrame::MANUAL);
+ __ EnterExitFrame(save_doubles_, x10, 3);
+ ASSERT(csp.Is(__ StackPointer()));
+
+ // Poke callee-saved registers into reserved space.
+ __ Poke(argv, 1 * kPointerSize);
+ __ Poke(argc, 2 * kPointerSize);
+ __ Poke(target, 3 * kPointerSize);
+
+ // We normally only keep tagged values in callee-saved registers, as they
+ // could be pushed onto the stack by called stubs and functions, and on the
+ // stack they can confuse the GC. However, we're only calling C functions
+ // which can push arbitrary data onto the stack anyway, and so the GC won't
+ // examine that part of the stack.
+ __ Mov(argc, argc_input);
+ __ Mov(target, target_input);
+ __ Mov(argv, temp_argv);
+
// x21 : argv
// x22 : argc
- // x23 : target
+ // x23 : call target
//
// The stack (on entry) holds the arguments and the receiver, with the
// receiver at the highest address:
@@ -1516,44 +1521,19 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
//
// After an unsuccessful call, the exit frame and suchlike are left
// untouched, and the stub either throws an exception by jumping to one of
- // the provided throw_ labels, or it falls through. The failure details are
- // passed through in x0.
- ASSERT(csp.Is(__ StackPointer()));
+ // the exception_returned label.
- Isolate* isolate = masm->isolate();
-
- const Register& argv = x21;
- const Register& argc = x22;
- const Register& target = x23;
-
- if (do_gc) {
- // Call Runtime::PerformGC, passing x0 (the result parameter for
- // PerformGC) and x1 (the isolate).
- __ Mov(x1, ExternalReference::isolate_address(masm->isolate()));
- __ CallCFunction(
- ExternalReference::perform_gc_function(isolate), 2, 0);
- }
-
- ExternalReference scope_depth =
- ExternalReference::heap_always_allocate_scope_depth(isolate);
- if (always_allocate) {
- __ Mov(x10, Operand(scope_depth));
- __ Ldr(x11, MemOperand(x10));
- __ Add(x11, x11, 1);
- __ Str(x11, MemOperand(x10));
- }
+ ASSERT(csp.Is(__ StackPointer()));
// Prepare AAPCS64 arguments to pass to the builtin.
__ Mov(x0, argc);
__ Mov(x1, argv);
- __ Mov(x2, ExternalReference::isolate_address(isolate));
+ __ Mov(x2, ExternalReference::isolate_address(isolate()));
- // Store the return address on the stack, in the space previously allocated
- // by EnterExitFrame. The return address is queried by
- // ExitFrame::GetStateForFramePointer.
Label return_location;
__ Adr(x12, &return_location);
__ Poke(x12, 0);
+
if (__ emit_debug_code()) {
// Verify that the slot below fp[kSPOffset]-8 points to the return location
// (currently in x12).
@@ -1568,27 +1548,17 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
// Call the builtin.
__ Blr(target);
__ Bind(&return_location);
- const Register& result = x0;
-
- if (always_allocate) {
- __ Mov(x10, Operand(scope_depth));
- __ Ldr(x11, MemOperand(x10));
- __ Sub(x11, x11, 1);
- __ Str(x11, MemOperand(x10));
- }
// x0 result The return code from the call.
// x21 argv
// x22 argc
// x23 target
- //
- // If all of the result bits matching kFailureTagMask are '1', the result is
- // a failure. Otherwise, it's an ordinary tagged object and the call was a
- // success.
- Label failure;
- __ And(x10, result, kFailureTagMask);
- __ Cmp(x10, kFailureTagMask);
- __ B(&failure, eq);
+ const Register& result = x0;
+
+ // Check result for exception sentinel.
+ Label exception_returned;
+ __ CompareRoot(result, Heap::kExceptionRootIndex);
+ __ B(eq, &exception_returned);
// The call succeeded, so unwind the stack and return.
@@ -1607,37 +1577,26 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
// jssp[8]: Preserved x22 (used for argc).
// jssp[0]: Preserved x21 (used for argv).
__ Drop(x11);
+ __ AssertFPCRState();
__ Ret();
// The stack pointer is still csp if we aren't returning, and the frame
// hasn't changed (except for the return address).
__ SetStackPointer(csp);
- __ Bind(&failure);
- // The call failed, so check if we need to throw an exception, and fall
- // through (to retry) otherwise.
-
- Label retry;
- // x0 result The return code from the call, including the failure
- // code and details.
- // x21 argv
- // x22 argc
- // x23 target
- // Refer to the Failure class for details of the bit layout.
- STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0);
- __ Tst(result, kFailureTypeTagMask << kFailureTagSize);
- __ B(eq, &retry); // RETRY_AFTER_GC
+ // Handling of exception.
+ __ Bind(&exception_returned);
// Retrieve the pending exception.
+ ExternalReference pending_exception_address(
+ Isolate::kPendingExceptionAddress, isolate());
const Register& exception = result;
const Register& exception_address = x11;
- __ Mov(exception_address,
- Operand(ExternalReference(Isolate::kPendingExceptionAddress,
- isolate)));
+ __ Mov(exception_address, Operand(pending_exception_address));
__ Ldr(exception, MemOperand(exception_address));
// Clear the pending exception.
- __ Mov(x10, Operand(isolate->factory()->the_hole_value()));
+ __ Mov(x10, Operand(isolate()->factory()->the_hole_value()));
__ Str(x10, MemOperand(exception_address));
// x0 exception The exception descriptor.
@@ -1647,118 +1606,9 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
// Special handling of termination exceptions, which are uncatchable by
// JavaScript code.
- __ Cmp(exception, Operand(isolate->factory()->termination_exception()));
- __ B(eq, throw_termination);
-
- // Handle normal exception.
- __ B(throw_normal);
-
- __ Bind(&retry);
- // The result (x0) is passed through as the next PerformGC parameter.
-}
-
-
-void CEntryStub::Generate(MacroAssembler* masm) {
- // The Abort mechanism relies on CallRuntime, which in turn relies on
- // CEntryStub, so until this stub has been generated, we have to use a
- // fall-back Abort mechanism.
- //
- // Note that this stub must be generated before any use of Abort.
- MacroAssembler::NoUseRealAbortsScope no_use_real_aborts(masm);
-
- ASM_LOCATION("CEntryStub::Generate entry");
- ProfileEntryHookStub::MaybeCallEntryHook(masm);
-
- // Register parameters:
- // x0: argc (including receiver, untagged)
- // x1: target
- //
- // The stack on entry holds the arguments and the receiver, with the receiver
- // at the highest address:
- //
- // jssp]argc-1]: receiver
- // jssp[argc-2]: arg[argc-2]
- // ... ...
- // jssp[1]: arg[1]
- // jssp[0]: arg[0]
- //
- // The arguments are in reverse order, so that arg[argc-2] is actually the
- // first argument to the target function and arg[0] is the last.
- ASSERT(jssp.Is(__ StackPointer()));
- const Register& argc_input = x0;
- const Register& target_input = x1;
-
- // Calculate argv, argc and the target address, and store them in
- // callee-saved registers so we can retry the call without having to reload
- // these arguments.
- // TODO(jbramley): If the first call attempt succeeds in the common case (as
- // it should), then we might be better off putting these parameters directly
- // into their argument registers, rather than using callee-saved registers and
- // preserving them on the stack.
- const Register& argv = x21;
- const Register& argc = x22;
- const Register& target = x23;
-
- // Derive argv from the stack pointer so that it points to the first argument
- // (arg[argc-2]), or just below the receiver in case there are no arguments.
- // - Adjust for the arg[] array.
- Register temp_argv = x11;
- __ Add(temp_argv, jssp, Operand(x0, LSL, kPointerSizeLog2));
- // - Adjust for the receiver.
- __ Sub(temp_argv, temp_argv, 1 * kPointerSize);
-
- // Enter the exit frame. Reserve three slots to preserve x21-x23 callee-saved
- // registers.
- FrameScope scope(masm, StackFrame::MANUAL);
- __ EnterExitFrame(save_doubles_, x10, 3);
- ASSERT(csp.Is(__ StackPointer()));
-
- // Poke callee-saved registers into reserved space.
- __ Poke(argv, 1 * kPointerSize);
- __ Poke(argc, 2 * kPointerSize);
- __ Poke(target, 3 * kPointerSize);
-
- // We normally only keep tagged values in callee-saved registers, as they
- // could be pushed onto the stack by called stubs and functions, and on the
- // stack they can confuse the GC. However, we're only calling C functions
- // which can push arbitrary data onto the stack anyway, and so the GC won't
- // examine that part of the stack.
- __ Mov(argc, argc_input);
- __ Mov(target, target_input);
- __ Mov(argv, temp_argv);
-
- Label throw_normal;
- Label throw_termination;
-
- // Call the runtime function.
- GenerateCore(masm,
- &throw_normal,
- &throw_termination,
- false,
- false);
-
- // If successful, the previous GenerateCore will have returned to the
- // calling code. Otherwise, we fall through into the following.
-
- // Do space-specific GC and retry runtime call.
- GenerateCore(masm,
- &throw_normal,
- &throw_termination,
- true,
- false);
-
- // Do full GC and retry runtime call one final time.
- __ Mov(x0, reinterpret_cast<uint64_t>(Failure::InternalError()));
- GenerateCore(masm,
- &throw_normal,
- &throw_termination,
- true,
- true);
-
- { FrameScope scope(masm, StackFrame::MANUAL);
- __ CallCFunction(
- ExternalReference::out_of_memory_function(masm->isolate()), 0);
- }
+ Label throw_termination_exception;
+ __ Cmp(exception, Operand(isolate()->factory()->termination_exception()));
+ __ B(eq, &throw_termination_exception);
// We didn't execute a return case, so the stack frame hasn't been updated
// (except for the return address slot). However, we don't need to initialize
@@ -1766,24 +1616,18 @@ void CEntryStub::Generate(MacroAssembler* masm) {
// unwinds the stack.
__ SetStackPointer(jssp);
- // Throw exceptions.
- // If we throw an exception, we can end up re-entering CEntryStub before we
- // pop the exit frame, so need to ensure that x21-x23 contain GC-safe values
- // here.
-
- __ Bind(&throw_termination);
- ASM_LOCATION("Throw termination");
+ ASM_LOCATION("Throw normal");
__ Mov(argv, 0);
__ Mov(argc, 0);
__ Mov(target, 0);
- __ ThrowUncatchable(x0, x10, x11, x12, x13);
+ __ Throw(x0, x10, x11, x12, x13);
- __ Bind(&throw_normal);
- ASM_LOCATION("Throw normal");
+ __ Bind(&throw_termination_exception);
+ ASM_LOCATION("Throw termination");
__ Mov(argv, 0);
__ Mov(argc, 0);
__ Mov(target, 0);
- __ Throw(x0, x10, x11, x12, x13);
+ __ ThrowUncatchable(x0, x10, x11, x12, x13);
}
@@ -1817,20 +1661,22 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
__ Mov(jssp, csp);
__ SetStackPointer(jssp);
+ // Configure the FPCR. We don't restore it, so this is technically not allowed
+ // according to AAPCS64. However, we only set default-NaN mode and this will
+ // be harmless for most C code. Also, it works for ARM.
+ __ ConfigureFPCR();
+
ProfileEntryHookStub::MaybeCallEntryHook(masm);
// Set up the reserved register for 0.0.
__ Fmov(fp_zero, 0.0);
// Build an entry frame (see layout below).
- Isolate* isolate = masm->isolate();
-
- // Build an entry frame.
int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
int64_t bad_frame_pointer = -1L; // Bad frame pointer to fail if it is used.
__ Mov(x13, bad_frame_pointer);
__ Mov(x12, Smi::FromInt(marker));
- __ Mov(x11, ExternalReference(Isolate::kCEntryFPAddress, isolate));
+ __ Mov(x11, ExternalReference(Isolate::kCEntryFPAddress, isolate()));
__ Ldr(x10, MemOperand(x11));
__ Push(x13, xzr, x12, x10);
@@ -1840,7 +1686,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// Push the JS entry frame marker. Also set js_entry_sp if this is the
// outermost JS call.
Label non_outermost_js, done;
- ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate);
+ ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate());
__ Mov(x10, ExternalReference(js_entry_sp));
__ Ldr(x11, MemOperand(x10));
__ Cbnz(x11, &non_outermost_js);
@@ -1880,10 +1726,10 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// fp will be invalid because the PushTryHandler below sets it to 0 to
// signal the existence of the JSEntry frame.
__ Mov(x10, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
- isolate)));
+ isolate())));
}
__ Str(code_entry, MemOperand(x10));
- __ Mov(x0, Operand(reinterpret_cast<int64_t>(Failure::Exception())));
+ __ LoadRoot(x0, Heap::kExceptionRootIndex);
__ B(&exit);
// Invoke: Link this frame into the handler chain. There's only one
@@ -1896,9 +1742,9 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// saved values before returning a failure to C.
// Clear any pending exceptions.
- __ Mov(x10, Operand(isolate->factory()->the_hole_value()));
+ __ Mov(x10, Operand(isolate()->factory()->the_hole_value()));
__ Mov(x11, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
- isolate)));
+ isolate())));
__ Str(x10, MemOperand(x11));
// Invoke the function by calling through the JS entry trampoline builtin.
@@ -1913,7 +1759,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// x4: argv.
ExternalReference entry(is_construct ? Builtins::kJSConstructEntryTrampoline
: Builtins::kJSEntryTrampoline,
- isolate);
+ isolate());
__ Mov(x10, entry);
// Call the JSEntryTrampoline.
@@ -1946,7 +1792,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// Restore the top frame descriptors from the stack.
__ Pop(x10);
- __ Mov(x11, ExternalReference(Isolate::kCEntryFPAddress, isolate));
+ __ Mov(x11, ExternalReference(Isolate::kCEntryFPAddress, isolate()));
__ Str(x10, MemOperand(x11));
// Reset the stack to the callee saved registers.
@@ -1973,7 +1819,7 @@ void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
// -----------------------------------
Register key = x0;
receiver = x1;
- __ Cmp(key, Operand(masm->isolate()->factory()->prototype_string()));
+ __ Cmp(key, Operand(isolate()->factory()->prototype_string()));
__ B(ne, &miss);
} else {
ASSERT(kind() == Code::LOAD_IC);
@@ -2131,7 +1977,7 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
__ Mov(result, res_false);
// Null is not instance of anything.
- __ Cmp(object_type, Operand(masm->isolate()->factory()->null_value()));
+ __ Cmp(object_type, Operand(isolate()->factory()->null_value()));
__ B(ne, &object_not_null);
__ Ret();
@@ -2732,11 +2578,10 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
const int kJSRegExpOffset = 7 * kPointerSize;
// Ensure that a RegExp stack is allocated.
- Isolate* isolate = masm->isolate();
ExternalReference address_of_regexp_stack_memory_address =
- ExternalReference::address_of_regexp_stack_memory_address(isolate);
+ ExternalReference::address_of_regexp_stack_memory_address(isolate());
ExternalReference address_of_regexp_stack_memory_size =
- ExternalReference::address_of_regexp_stack_memory_size(isolate);
+ ExternalReference::address_of_regexp_stack_memory_size(isolate());
__ Mov(x10, address_of_regexp_stack_memory_size);
__ Ldr(x10, MemOperand(x10));
__ Cbz(x10, &runtime);
@@ -2898,7 +2743,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ JumpIfSmi(code_object, &runtime);
// All checks done. Now push arguments for native regexp code.
- __ IncrementCounter(isolate->counters()->regexp_entry_native(), 1,
+ __ IncrementCounter(isolate()->counters()->regexp_entry_native(), 1,
x10,
x11);
@@ -2914,7 +2759,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// csp[0]: Space for the return address placed by DirectCEntryStub.
// csp[8]: Argument 9, the current isolate address.
- __ Mov(x10, ExternalReference::isolate_address(isolate));
+ __ Mov(x10, ExternalReference::isolate_address(isolate()));
__ Poke(x10, kPointerSize);
Register length = w11;
@@ -2963,7 +2808,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ Add(x3, x2, Operand(w10, UXTW));
// Argument 5 (x4): static offsets vector buffer.
- __ Mov(x4, ExternalReference::address_of_static_offsets_vector(isolate));
+ __ Mov(x4, ExternalReference::address_of_static_offsets_vector(isolate()));
// Argument 6 (x5): Set the number of capture registers to zero to force
// global regexps to behave as non-global. This stub is not used for global
@@ -2982,7 +2827,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Locate the code entry and call it.
__ Add(code_object, code_object, Code::kHeaderSize - kHeapObjectTag);
- DirectCEntryStub stub;
+ DirectCEntryStub stub(isolate());
stub.GenerateCall(masm, code_object);
__ LeaveExitFrame(false, x10, true);
@@ -3068,7 +2913,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Get the static offsets vector filled by the native regexp code
// and fill the last match info.
ExternalReference address_of_static_offsets_vector =
- ExternalReference::address_of_static_offsets_vector(isolate);
+ ExternalReference::address_of_static_offsets_vector(isolate());
__ Mov(offsets_vector_index, address_of_static_offsets_vector);
Label next_capture, done;
@@ -3107,10 +2952,10 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// A stack overflow (on the backtrack stack) may have occured
// in the RegExp code but no exception has been created yet.
// If there is no pending exception, handle that in the runtime system.
- __ Mov(x10, Operand(isolate->factory()->the_hole_value()));
+ __ Mov(x10, Operand(isolate()->factory()->the_hole_value()));
__ Mov(x11,
Operand(ExternalReference(Isolate::kPendingExceptionAddress,
- isolate)));
+ isolate())));
__ Ldr(exception_value, MemOperand(x11));
__ Cmp(x10, exception_value);
__ B(eq, &runtime);
@@ -3129,7 +2974,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ ThrowUncatchable(exception_value, x10, x11, x12, x13);
__ Bind(&failure);
- __ Mov(x0, Operand(masm->isolate()->factory()->null_value()));
+ __ Mov(x0, Operand(isolate()->factory()->null_value()));
__ PopCPURegList(used_callee_saved_registers);
// Drop the 4 arguments of the stub from the stack.
__ Drop(4);
@@ -3259,7 +3104,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm,
// slot.
{
FrameScope scope(masm, StackFrame::INTERNAL);
- CreateAllocationSiteStub create_stub;
+ CreateAllocationSiteStub create_stub(masm->isolate());
// Arguments register must be smi-tagged to call out.
__ SmiTag(argc);
@@ -3294,14 +3139,64 @@ static void GenerateRecordCallTarget(MacroAssembler* masm,
}
+static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
+ // Do not transform the receiver for strict mode functions.
+ __ Ldr(x3, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
+ __ Ldr(w4, FieldMemOperand(x3, SharedFunctionInfo::kCompilerHintsOffset));
+ __ Tbnz(w4, SharedFunctionInfo::kStrictModeFunction, cont);
+
+ // Do not transform the receiver for native (Compilerhints already in x3).
+ __ Tbnz(w4, SharedFunctionInfo::kNative, cont);
+}
+
+
+static void EmitSlowCase(MacroAssembler* masm,
+ int argc,
+ Register function,
+ Register type,
+ Label* non_function) {
+ // Check for function proxy.
+ // x10 : function type.
+ __ CompareAndBranch(type, JS_FUNCTION_PROXY_TYPE, ne, non_function);
+ __ Push(function); // put proxy as additional argument
+ __ Mov(x0, argc + 1);
+ __ Mov(x2, 0);
+ __ GetBuiltinFunction(x1, Builtins::CALL_FUNCTION_PROXY);
+ {
+ Handle<Code> adaptor =
+ masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
+ __ Jump(adaptor, RelocInfo::CODE_TARGET);
+ }
+
+ // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
+ // of the original receiver from the call site).
+ __ Bind(non_function);
+ __ Poke(function, argc * kXRegSize);
+ __ Mov(x0, argc); // Set up the number of arguments.
+ __ Mov(x2, 0);
+ __ GetBuiltinFunction(function, Builtins::CALL_NON_FUNCTION);
+ __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+ RelocInfo::CODE_TARGET);
+}
+
+
+static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) {
+ // Wrap the receiver and patch it back onto the stack.
+ { FrameScope frame_scope(masm, StackFrame::INTERNAL);
+ __ Push(x1, x3);
+ __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
+ __ Pop(x1);
+ }
+ __ Poke(x0, argc * kPointerSize);
+ __ B(cont);
+}
+
+
void CallFunctionStub::Generate(MacroAssembler* masm) {
ASM_LOCATION("CallFunctionStub::Generate");
// x1 function the function to call
- // x2 : feedback vector
- // x3 : slot in feedback vector (smi) (if x2 is not the megamorphic symbol)
+
Register function = x1;
- Register cache_cell = x2;
- Register slot = x3;
Register type = x4;
Label slow, non_function, wrap, cont;
@@ -3314,33 +3209,20 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// Goto slow case if we do not have a function.
__ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow);
-
- if (RecordCallTarget()) {
- GenerateRecordCallTarget(masm, x0, function, cache_cell, slot, x4, x5);
- // Type information was updated. Because we may call Array, which
- // expects either undefined or an AllocationSite in ebx we need
- // to set ebx to undefined.
- __ LoadRoot(cache_cell, Heap::kUndefinedValueRootIndex);
- }
}
// Fast-case: Invoke the function now.
// x1 function pushed function
- ParameterCount actual(argc_);
+ int argc = argc_;
+ ParameterCount actual(argc);
if (CallAsMethod()) {
if (NeedsChecks()) {
- // Do not transform the receiver for strict mode functions.
- __ Ldr(x3, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
- __ Ldr(w4, FieldMemOperand(x3, SharedFunctionInfo::kCompilerHintsOffset));
- __ Tbnz(w4, SharedFunctionInfo::kStrictModeFunction, &cont);
-
- // Do not transform the receiver for native (Compilerhints already in x3).
- __ Tbnz(w4, SharedFunctionInfo::kNative, &cont);
+ EmitContinueIfStrictOrNative(masm, &cont);
}
// Compute the receiver in sloppy mode.
- __ Peek(x3, argc_ * kPointerSize);
+ __ Peek(x3, argc * kPointerSize);
if (NeedsChecks()) {
__ JumpIfSmi(x3, &wrap);
@@ -3351,6 +3233,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
__ Bind(&cont);
}
+
__ InvokeFunction(function,
actual,
JUMP_FUNCTION,
@@ -3359,51 +3242,12 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
if (NeedsChecks()) {
// Slow-case: Non-function called.
__ Bind(&slow);
- if (RecordCallTarget()) {
- // If there is a call target cache, mark it megamorphic in the
- // non-function case. MegamorphicSentinel is an immortal immovable object
- // (megamorphic symbol) so no write barrier is needed.
- ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
- masm->isolate()->heap()->megamorphic_symbol());
- __ Add(x12, cache_cell, Operand::UntagSmiAndScale(slot,
- kPointerSizeLog2));
- __ LoadRoot(x11, Heap::kMegamorphicSymbolRootIndex);
- __ Str(x11, FieldMemOperand(x12, FixedArray::kHeaderSize));
- }
- // Check for function proxy.
- // x10 : function type.
- __ CompareAndBranch(type, JS_FUNCTION_PROXY_TYPE, ne, &non_function);
- __ Push(function); // put proxy as additional argument
- __ Mov(x0, argc_ + 1);
- __ Mov(x2, 0);
- __ GetBuiltinFunction(x1, Builtins::CALL_FUNCTION_PROXY);
- {
- Handle<Code> adaptor =
- masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
- __ Jump(adaptor, RelocInfo::CODE_TARGET);
- }
-
- // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
- // of the original receiver from the call site).
- __ Bind(&non_function);
- __ Poke(function, argc_ * kXRegSize);
- __ Mov(x0, argc_); // Set up the number of arguments.
- __ Mov(x2, 0);
- __ GetBuiltinFunction(function, Builtins::CALL_NON_FUNCTION);
- __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
- RelocInfo::CODE_TARGET);
+ EmitSlowCase(masm, argc, function, type, &non_function);
}
if (CallAsMethod()) {
__ Bind(&wrap);
- // Wrap the receiver and patch it back onto the stack.
- { FrameScope frame_scope(masm, StackFrame::INTERNAL);
- __ Push(x1, x3);
- __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
- __ Pop(x1);
- }
- __ Poke(x0, argc_ * kPointerSize);
- __ B(&cont);
+ EmitWrapCase(masm, argc, &cont);
}
}
@@ -3473,11 +3317,126 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
__ Bind(&do_call);
// Set expected number of arguments to zero (not changing x0).
__ Mov(x2, 0);
- __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+ __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET);
}
+static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
+ __ Ldr(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+ __ Ldr(vector, FieldMemOperand(vector,
+ JSFunction::kSharedFunctionInfoOffset));
+ __ Ldr(vector, FieldMemOperand(vector,
+ SharedFunctionInfo::kFeedbackVectorOffset));
+}
+
+
+void CallICStub::Generate(MacroAssembler* masm) {
+ ASM_LOCATION("CallICStub");
+
+ // x1 - function
+ // x3 - slot id (Smi)
+ Label extra_checks_or_miss, slow_start;
+ Label slow, non_function, wrap, cont;
+ Label have_js_function;
+ int argc = state_.arg_count();
+ ParameterCount actual(argc);
+
+ Register function = x1;
+ Register feedback_vector = x2;
+ Register index = x3;
+ Register type = x4;
+
+ EmitLoadTypeFeedbackVector(masm, feedback_vector);
+
+ // The checks. First, does x1 match the recorded monomorphic target?
+ __ Add(x4, feedback_vector,
+ Operand::UntagSmiAndScale(index, kPointerSizeLog2));
+ __ Ldr(x4, FieldMemOperand(x4, FixedArray::kHeaderSize));
+
+ __ Cmp(x4, function);
+ __ B(ne, &extra_checks_or_miss);
+
+ __ bind(&have_js_function);
+ if (state_.CallAsMethod()) {
+ EmitContinueIfStrictOrNative(masm, &cont);
+
+ // Compute the receiver in sloppy mode.
+ __ Peek(x3, argc * kPointerSize);
+
+ __ JumpIfSmi(x3, &wrap);
+ __ JumpIfObjectType(x3, x10, type, FIRST_SPEC_OBJECT_TYPE, &wrap, lt);
+
+ __ Bind(&cont);
+ }
+
+ __ InvokeFunction(function,
+ actual,
+ JUMP_FUNCTION,
+ NullCallWrapper());
+
+ __ bind(&slow);
+ EmitSlowCase(masm, argc, function, type, &non_function);
+
+ if (state_.CallAsMethod()) {
+ __ bind(&wrap);
+ EmitWrapCase(masm, argc, &cont);
+ }
+
+ __ bind(&extra_checks_or_miss);
+ Label miss;
+
+ __ JumpIfRoot(x4, Heap::kMegamorphicSymbolRootIndex, &slow_start);
+ __ JumpIfRoot(x4, Heap::kUninitializedSymbolRootIndex, &miss);
+
+ if (!FLAG_trace_ic) {
+ // We are going megamorphic, and we don't want to visit the runtime.
+ __ Add(x4, feedback_vector,
+ Operand::UntagSmiAndScale(index, kPointerSizeLog2));
+ __ LoadRoot(x5, Heap::kMegamorphicSymbolRootIndex);
+ __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize));
+ __ B(&slow_start);
+ }
+
+ // We are here because tracing is on or we are going monomorphic.
+ __ bind(&miss);
+ GenerateMiss(masm);
+
+ // the slow case
+ __ bind(&slow_start);
+
+ // Check that the function is really a JavaScript function.
+ __ JumpIfSmi(function, &non_function);
+
+ // Goto slow case if we do not have a function.
+ __ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow);
+ __ B(&have_js_function);
+}
+
+
+void CallICStub::GenerateMiss(MacroAssembler* masm) {
+ ASM_LOCATION("CallICStub[Miss]");
+
+ // Get the receiver of the function from the stack; 1 ~ return address.
+ __ Peek(x4, (state_.arg_count() + 1) * kPointerSize);
+
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+
+ // Push the receiver and the function and feedback info.
+ __ Push(x4, x1, x2, x3);
+
+ // Call the entry.
+ ExternalReference miss = ExternalReference(IC_Utility(IC::kCallIC_Miss),
+ masm->isolate());
+ __ CallExternalReference(miss, 4);
+
+ // Move result to edi and exit the internal frame.
+ __ Mov(x1, x0);
+ }
+}
+
+
void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
// If the receiver is a smi trigger the non-string case.
__ JumpIfSmi(object_, receiver_not_string_);
@@ -3663,9 +3622,9 @@ void ICCompareStub::GenerateNumbers(MacroAssembler* masm) {
__ Ret();
__ Bind(&unordered);
- ICCompareStub stub(op_, CompareIC::GENERIC, CompareIC::GENERIC,
+ ICCompareStub stub(isolate(), op_, CompareIC::GENERIC, CompareIC::GENERIC,
CompareIC::GENERIC);
- __ Jump(stub.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
+ __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
__ Bind(&maybe_undefined1);
if (Token::IsOrderedRelationalCompareOp(op_)) {
@@ -3905,7 +3864,7 @@ void ICCompareStub::GenerateMiss(MacroAssembler* masm) {
Register stub_entry = x11;
{
ExternalReference miss =
- ExternalReference(IC_Utility(IC::kCompareIC_Miss), masm->isolate());
+ ExternalReference(IC_Utility(IC::kCompareIC_Miss), isolate());
FrameScope scope(masm, StackFrame::INTERNAL);
Register op = x10;
@@ -4219,7 +4178,7 @@ void SubStringStub::Generate(MacroAssembler* masm) {
__ CopyBytes(result_char0, substring_char0, result_length, x3, kCopyLong);
__ Bind(&return_x0);
- Counters* counters = masm->isolate()->counters();
+ Counters* counters = isolate()->counters();
__ IncrementCounter(counters->sub_string_native(), 1, x3, x4);
__ Drop(3);
__ Ret();
@@ -4366,7 +4325,7 @@ void StringCompareStub::GenerateAsciiCharsCompareLoop(
void StringCompareStub::Generate(MacroAssembler* masm) {
Label runtime;
- Counters* counters = masm->isolate()->counters();
+ Counters* counters = isolate()->counters();
// Stack frame on entry.
// sp[0]: right string
@@ -4406,227 +4365,17 @@ void StringCompareStub::Generate(MacroAssembler* masm) {
}
-void ArrayPushStub::Generate(MacroAssembler* masm) {
- Register receiver = x0;
-
- int argc = arguments_count();
-
- if (argc == 0) {
- // Nothing to do, just return the length.
- __ Ldr(x0, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ Drop(argc + 1);
- __ Ret();
- return;
- }
-
- Isolate* isolate = masm->isolate();
-
- if (argc != 1) {
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- Label call_builtin, attempt_to_grow_elements, with_write_barrier;
-
- Register elements_length = x8;
- Register length = x7;
- Register elements = x6;
- Register end_elements = x5;
- Register value = x4;
- // Get the elements array of the object.
- __ Ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- // Check that the elements are in fast mode and writable.
- __ CheckMap(elements,
- x10,
- Heap::kFixedArrayMapRootIndex,
- &call_builtin,
- DONT_DO_SMI_CHECK);
- }
-
- // Get the array's length and calculate new length.
- __ Ldr(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
- STATIC_ASSERT(kSmiTag == 0);
- __ Add(length, length, Smi::FromInt(argc));
-
- // Check if we could survive without allocation.
- __ Ldr(elements_length,
- FieldMemOperand(elements, FixedArray::kLengthOffset));
- __ Cmp(length, elements_length);
-
- const int kEndElementsOffset =
- FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize;
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- __ B(gt, &attempt_to_grow_elements);
-
- // Check if value is a smi.
- __ Peek(value, (argc - 1) * kPointerSize);
- __ JumpIfNotSmi(value, &with_write_barrier);
-
- // Store the value.
- // We may need a register containing the address end_elements below,
- // so write back the value in end_elements.
- __ Add(end_elements, elements,
- Operand::UntagSmiAndScale(length, kPointerSizeLog2));
- __ Str(value, MemOperand(end_elements, kEndElementsOffset, PreIndex));
- } else {
- __ B(gt, &call_builtin);
-
- __ Peek(value, (argc - 1) * kPointerSize);
- __ StoreNumberToDoubleElements(value, length, elements, x10, d0, d1,
- &call_builtin, argc * kDoubleSize);
- }
-
- // Save new length.
- __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
-
- // Return length.
- __ Drop(argc + 1);
- __ Mov(x0, length);
- __ Ret();
-
- if (IsFastDoubleElementsKind(elements_kind())) {
- __ Bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ Bind(&with_write_barrier);
-
- if (IsFastSmiElementsKind(elements_kind())) {
- if (FLAG_trace_elements_transitions) {
- __ B(&call_builtin);
- }
-
- __ Ldr(x10, FieldMemOperand(value, HeapObject::kMapOffset));
- __ JumpIfHeapNumber(x10, &call_builtin);
-
- ElementsKind target_kind = IsHoleyElementsKind(elements_kind())
- ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
- __ Ldr(x10, GlobalObjectMemOperand());
- __ Ldr(x10, FieldMemOperand(x10, GlobalObject::kNativeContextOffset));
- __ Ldr(x10, ContextMemOperand(x10, Context::JS_ARRAY_MAPS_INDEX));
- const int header_size = FixedArrayBase::kHeaderSize;
- // Verify that the object can be transitioned in place.
- const int origin_offset = header_size + elements_kind() * kPointerSize;
- __ ldr(x11, FieldMemOperand(receiver, origin_offset));
- __ ldr(x12, FieldMemOperand(x10, HeapObject::kMapOffset));
- __ cmp(x11, x12);
- __ B(ne, &call_builtin);
-
- const int target_offset = header_size + target_kind * kPointerSize;
- __ Ldr(x10, FieldMemOperand(x10, target_offset));
- __ Mov(x11, receiver);
- ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
- masm, DONT_TRACK_ALLOCATION_SITE, NULL);
- }
-
- // Save new length.
- __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
-
- // Store the value.
- // We may need a register containing the address end_elements below,
- // so write back the value in end_elements.
- __ Add(end_elements, elements,
- Operand::UntagSmiAndScale(length, kPointerSizeLog2));
- __ Str(value, MemOperand(end_elements, kEndElementsOffset, PreIndex));
-
- __ RecordWrite(elements,
- end_elements,
- value,
- kLRHasNotBeenSaved,
- kDontSaveFPRegs,
- EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
- __ Drop(argc + 1);
- __ Mov(x0, length);
- __ Ret();
-
- __ Bind(&attempt_to_grow_elements);
-
- if (!FLAG_inline_new) {
- __ B(&call_builtin);
- }
-
- Register argument = x2;
- __ Peek(argument, (argc - 1) * kPointerSize);
- // Growing elements that are SMI-only requires special handling in case
- // the new element is non-Smi. For now, delegate to the builtin.
- if (IsFastSmiElementsKind(elements_kind())) {
- __ JumpIfNotSmi(argument, &call_builtin);
- }
-
- // We could be lucky and the elements array could be at the top of new-space.
- // In this case we can just grow it in place by moving the allocation pointer
- // up.
- ExternalReference new_space_allocation_top =
- ExternalReference::new_space_allocation_top_address(isolate);
- ExternalReference new_space_allocation_limit =
- ExternalReference::new_space_allocation_limit_address(isolate);
-
- const int kAllocationDelta = 4;
- ASSERT(kAllocationDelta >= argc);
- Register allocation_top_addr = x5;
- Register allocation_top = x9;
- // Load top and check if it is the end of elements.
- __ Add(end_elements, elements,
- Operand::UntagSmiAndScale(length, kPointerSizeLog2));
- __ Add(end_elements, end_elements, kEndElementsOffset);
- __ Mov(allocation_top_addr, new_space_allocation_top);
- __ Ldr(allocation_top, MemOperand(allocation_top_addr));
- __ Cmp(end_elements, allocation_top);
- __ B(ne, &call_builtin);
-
- __ Mov(x10, new_space_allocation_limit);
- __ Ldr(x10, MemOperand(x10));
- __ Add(allocation_top, allocation_top, kAllocationDelta * kPointerSize);
- __ Cmp(allocation_top, x10);
- __ B(hi, &call_builtin);
-
- // We fit and could grow elements.
- // Update new_space_allocation_top.
- __ Str(allocation_top, MemOperand(allocation_top_addr));
- // Push the argument.
- __ Str(argument, MemOperand(end_elements));
- // Fill the rest with holes.
- __ LoadRoot(x10, Heap::kTheHoleValueRootIndex);
- ASSERT(kAllocationDelta == 4);
- __ Stp(x10, x10, MemOperand(end_elements, 1 * kPointerSize));
- __ Stp(x10, x10, MemOperand(end_elements, 3 * kPointerSize));
-
- // Update elements' and array's sizes.
- __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ Add(elements_length, elements_length, Smi::FromInt(kAllocationDelta));
- __ Str(elements_length,
- FieldMemOperand(elements, FixedArray::kLengthOffset));
-
- // Elements are in new space, so write barrier is not required.
- __ Drop(argc + 1);
- __ Mov(x0, length);
- __ Ret();
-
- __ Bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
-}
-
-
void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- x1 : left
// -- x0 : right
// -- lr : return address
// -----------------------------------
- Isolate* isolate = masm->isolate();
// Load x2 with the allocation site. We stick an undefined dummy value here
// and replace it with the real allocation site later when we instantiate this
// stub in BinaryOpICWithAllocationSiteStub::GetCodeCopyFromTemplate().
- __ LoadObject(x2, handle(isolate->heap()->undefined_value()));
+ __ LoadObject(x2, handle(isolate()->heap()->undefined_value()));
// Make sure that we actually patched the allocation site.
if (FLAG_debug_code) {
@@ -4638,7 +4387,7 @@ void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
// Tail call into the stub that handles binary operations with allocation
// sites.
- BinaryOpWithAllocationSiteStub stub(state_);
+ BinaryOpWithAllocationSiteStub stub(isolate(), state_);
__ TailCallStub(&stub);
}
@@ -4699,12 +4448,12 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
__ Mov(address, regs_.address());
__ Mov(x0, regs_.object());
__ Mov(x1, address);
- __ Mov(x2, ExternalReference::isolate_address(masm->isolate()));
+ __ Mov(x2, ExternalReference::isolate_address(isolate()));
AllowExternalCallThatCantCauseGC scope(masm);
ExternalReference function =
ExternalReference::incremental_marking_record_write_function(
- masm->isolate());
+ isolate());
__ CallCFunction(function, 3, 0);
regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode_);
@@ -4890,15 +4639,15 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
__ Bind(&double_elements);
__ Ldr(x10, FieldMemOperand(array, JSObject::kElementsOffset));
- __ StoreNumberToDoubleElements(value, index_smi, x10, x11, d0, d1,
+ __ StoreNumberToDoubleElements(value, index_smi, x10, x11, d0,
&slow_elements);
__ Ret();
}
void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
- CEntryStub ces(1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
- __ Call(ces.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
+ CEntryStub ces(isolate(), 1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
+ __ Call(ces.GetCode(), RelocInfo::CODE_TARGET);
int parameter_count_offset =
StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
__ Ldr(x1, MemOperand(fp, parameter_count_offset));
@@ -4920,7 +4669,7 @@ static const unsigned int kProfileEntryHookCallSize =
void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
if (masm->isolate()->function_entry_hook() != NULL) {
- ProfileEntryHookStub stub;
+ ProfileEntryHookStub stub(masm->isolate());
Assembler::BlockConstPoolScope no_const_pools(masm);
Label entry_hook_call_start;
__ Bind(&entry_hook_call_start);
@@ -4949,7 +4698,7 @@ void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
#if V8_HOST_ARCH_ARM64
uintptr_t entry_hook =
- reinterpret_cast<uintptr_t>(masm->isolate()->function_entry_hook());
+ reinterpret_cast<uintptr_t>(isolate()->function_entry_hook());
__ Mov(x10, entry_hook);
#else
// Under the simulator we need to indirect the entry hook through a trampoline
@@ -4957,9 +4706,9 @@ void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
ApiFunction dispatcher(FUNCTION_ADDR(EntryHookTrampoline));
__ Mov(x10, Operand(ExternalReference(&dispatcher,
ExternalReference::BUILTIN_CALL,
- masm->isolate())));
+ isolate())));
// It additionally takes an isolate as a third parameter
- __ Mov(x2, ExternalReference::isolate_address(masm->isolate()));
+ __ Mov(x2, ExternalReference::isolate_address(isolate()));
#endif
// The caller's return address is above the saved temporaries.
@@ -4992,6 +4741,7 @@ void DirectCEntryStub::Generate(MacroAssembler* masm) {
__ Blr(x10);
// Return to calling code.
__ Peek(lr, 0);
+ __ AssertFPCRState();
__ Ret();
__ SetStackPointer(old_stack_pointer);
@@ -5004,7 +4754,7 @@ void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
ASSERT(csp.Is(__ StackPointer()));
intptr_t code =
- reinterpret_cast<intptr_t>(GetCode(masm->isolate()).location());
+ reinterpret_cast<intptr_t>(GetCode().location());
__ Mov(lr, Operand(code, RelocInfo::CODE_TARGET));
__ Mov(x10, target);
// Branch to the stub.
@@ -5083,7 +4833,7 @@ void NameDictionaryLookupStub::GeneratePositiveLookup(
}
Label not_found;
- NameDictionaryLookupStub stub(POSITIVE_LOOKUP);
+ NameDictionaryLookupStub stub(masm->isolate(), POSITIVE_LOOKUP);
__ CallStub(&stub);
__ Cbz(x0, &not_found);
__ Mov(scratch2, x2); // Move entry index into scratch2.
@@ -5154,7 +4904,7 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
__ Ldr(x0, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
__ Mov(x1, Operand(name));
- NameDictionaryLookupStub stub(NEGATIVE_LOOKUP);
+ NameDictionaryLookupStub stub(masm->isolate(), NEGATIVE_LOOKUP);
__ CallStub(&stub);
// Move stub return value to scratch0. Note that scratch0 is not included in
// spill_list and won't be clobbered by PopCPURegList.
@@ -5257,7 +5007,7 @@ static void CreateArrayDispatch(MacroAssembler* masm,
AllocationSiteOverrideMode mode) {
ASM_LOCATION("CreateArrayDispatch");
if (mode == DISABLE_ALLOCATION_SITES) {
- T stub(GetInitialFastElementsKind(), mode);
+ T stub(masm->isolate(), GetInitialFastElementsKind(), mode);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
@@ -5270,7 +5020,7 @@ static void CreateArrayDispatch(MacroAssembler* masm,
// TODO(jbramley): Is this the best way to handle this? Can we make the
// tail calls conditional, rather than hopping over each one?
__ CompareAndBranch(kind, candidate_kind, ne, &next);
- T stub(candidate_kind);
+ T stub(masm->isolate(), candidate_kind);
__ TailCallStub(&stub);
__ Bind(&next);
}
@@ -5320,12 +5070,14 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
ElementsKind initial = GetInitialFastElementsKind();
ElementsKind holey_initial = GetHoleyElementsKind(initial);
- ArraySingleArgumentConstructorStub stub_holey(holey_initial,
+ ArraySingleArgumentConstructorStub stub_holey(masm->isolate(),
+ holey_initial,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub_holey);
__ Bind(&normal_sequence);
- ArraySingleArgumentConstructorStub stub(initial,
+ ArraySingleArgumentConstructorStub stub(masm->isolate(),
+ initial,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
@@ -5357,7 +5109,7 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
Label next;
ElementsKind candidate_kind = GetFastElementsKindFromSequenceIndex(i);
__ CompareAndBranch(kind, candidate_kind, ne, &next);
- ArraySingleArgumentConstructorStub stub(candidate_kind);
+ ArraySingleArgumentConstructorStub stub(masm->isolate(), candidate_kind);
__ TailCallStub(&stub);
__ Bind(&next);
}
@@ -5376,11 +5128,11 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
TERMINAL_FAST_ELEMENTS_KIND);
for (int i = 0; i <= to_index; ++i) {
ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
- T stub(kind);
- stub.GetCode(isolate);
+ T stub(isolate, kind);
+ stub.GetCode();
if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
- T stub1(kind, DISABLE_ALLOCATION_SITES);
- stub1.GetCode(isolate);
+ T stub1(isolate, kind, DISABLE_ALLOCATION_SITES);
+ stub1.GetCode();
}
}
}
@@ -5401,12 +5153,12 @@ void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
for (int i = 0; i < 2; i++) {
// For internal arrays we only need a few things
- InternalArrayNoArgumentConstructorStub stubh1(kinds[i]);
- stubh1.GetCode(isolate);
- InternalArraySingleArgumentConstructorStub stubh2(kinds[i]);
- stubh2.GetCode(isolate);
- InternalArrayNArgumentsConstructorStub stubh3(kinds[i]);
- stubh3.GetCode(isolate);
+ InternalArrayNoArgumentConstructorStub stubh1(isolate, kinds[i]);
+ stubh1.GetCode();
+ InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]);
+ stubh2.GetCode();
+ InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]);
+ stubh3.GetCode();
}
}
@@ -5509,22 +5261,22 @@ void InternalArrayConstructorStub::GenerateCase(
__ Cbz(x10, &packed_case);
InternalArraySingleArgumentConstructorStub
- stub1_holey(GetHoleyElementsKind(kind));
+ stub1_holey(isolate(), GetHoleyElementsKind(kind));
__ TailCallStub(&stub1_holey);
__ Bind(&packed_case);
}
- InternalArraySingleArgumentConstructorStub stub1(kind);
+ InternalArraySingleArgumentConstructorStub stub1(isolate(), kind);
__ TailCallStub(&stub1);
__ Bind(&zero_case);
// No arguments.
- InternalArrayNoArgumentConstructorStub stub0(kind);
+ InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
__ TailCallStub(&stub0);
__ Bind(&n_case);
// N arguments.
- InternalArrayNArgumentsConstructorStub stubN(kind);
+ InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
__ TailCallStub(&stubN);
}
@@ -5536,8 +5288,6 @@ void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
// -- sp[0] : return address
// -- sp[4] : last argument
// -----------------------------------
- Handle<Object> undefined_sentinel(
- masm->isolate()->heap()->undefined_value(), masm->isolate());
Register constructor = x1;
@@ -5616,8 +5366,6 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(FCA::kHolderIndex == 0);
STATIC_ASSERT(FCA::kArgsLength == 7);
- Isolate* isolate = masm->isolate();
-
// FunctionCallbackArguments: context, callee and call data.
__ Push(context, callee, call_data);
@@ -5628,7 +5376,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
__ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
}
Register isolate_reg = x5;
- __ Mov(isolate_reg, ExternalReference::isolate_address(isolate));
+ __ Mov(isolate_reg, ExternalReference::isolate_address(isolate()));
// FunctionCallbackArguments:
// return value, return value default, isolate, holder.
@@ -5662,11 +5410,8 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
__ Stp(x10, xzr, MemOperand(x0, 2 * kPointerSize));
const int kStackUnwindSpace = argc + FCA::kArgsLength + 1;
- Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
- ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
- ApiFunction thunk_fun(thunk_address);
- ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
- masm->isolate());
+ ExternalReference thunk_ref =
+ ExternalReference::invoke_function_callback(isolate());
AllowExternalCallThatCantCauseGC scope(masm);
MemOperand context_restore_operand(
@@ -5719,12 +5464,8 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
- Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
- ExternalReference::Type thunk_type =
- ExternalReference::PROFILING_GETTER_CALL;
- ApiFunction thunk_fun(thunk_address);
- ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
- masm->isolate());
+ ExternalReference thunk_ref =
+ ExternalReference::invoke_accessor_getter_callback(isolate());
const int spill_offset = 1 + kApiStackSpace;
__ CallApiFunctionAndReturn(api_function_address,
diff --git a/deps/v8/src/arm64/code-stubs-arm64.h b/deps/v8/src/arm64/code-stubs-arm64.h
index 7e09ffa57c..a92445c47a 100644
--- a/deps/v8/src/arm64/code-stubs-arm64.h
+++ b/deps/v8/src/arm64/code-stubs-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_CODE_STUBS_ARM64_H_
#define V8_ARM64_CODE_STUBS_ARM64_H_
@@ -39,8 +16,8 @@ void ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code);
class StoreBufferOverflowStub: public PlatformCodeStub {
public:
- explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp)
- : save_doubles_(save_fp) { }
+ StoreBufferOverflowStub(Isolate* isolate, SaveFPRegsMode save_fp)
+ : PlatformCodeStub(isolate), save_doubles_(save_fp) { }
void Generate(MacroAssembler* masm);
@@ -79,8 +56,8 @@ class StringHelper : public AllStatic {
class StoreRegistersStateStub: public PlatformCodeStub {
public:
- explicit StoreRegistersStateStub(SaveFPRegsMode with_fp)
- : save_doubles_(with_fp) {}
+ StoreRegistersStateStub(Isolate* isolate, SaveFPRegsMode with_fp)
+ : PlatformCodeStub(isolate), save_doubles_(with_fp) {}
static Register to_be_pushed_lr() { return ip0; }
static void GenerateAheadOfTime(Isolate* isolate);
@@ -95,8 +72,8 @@ class StoreRegistersStateStub: public PlatformCodeStub {
class RestoreRegistersStateStub: public PlatformCodeStub {
public:
- explicit RestoreRegistersStateStub(SaveFPRegsMode with_fp)
- : save_doubles_(with_fp) {}
+ RestoreRegistersStateStub(Isolate* isolate, SaveFPRegsMode with_fp)
+ : PlatformCodeStub(isolate), save_doubles_(with_fp) {}
static void GenerateAheadOfTime(Isolate* isolate);
private:
@@ -113,12 +90,14 @@ class RecordWriteStub: public PlatformCodeStub {
// Stub to record the write of 'value' at 'address' in 'object'.
// Typically 'address' = 'object' + <some offset>.
// See MacroAssembler::RecordWriteField() for example.
- RecordWriteStub(Register object,
+ RecordWriteStub(Isolate* isolate,
+ Register object,
Register value,
Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode)
- : object_(object),
+ : PlatformCodeStub(isolate),
+ object_(object),
value_(value),
address_(address),
remembered_set_action_(remembered_set_action),
@@ -210,9 +189,15 @@ class RecordWriteStub: public PlatformCodeStub {
: object_(object),
address_(address),
scratch0_(scratch),
- saved_regs_(kCallerSaved) {
+ saved_regs_(kCallerSaved),
+ saved_fp_regs_(kCallerSavedFP) {
ASSERT(!AreAliased(scratch, object, address));
+ // The SaveCallerSaveRegisters method needs to save caller-saved
+ // registers, but we don't bother saving MacroAssembler scratch registers.
+ saved_regs_.Remove(MacroAssembler::DefaultTmpList());
+ saved_fp_regs_.Remove(MacroAssembler::DefaultFPTmpList());
+
// We would like to require more scratch registers for this stub,
// but the number of registers comes down to the ones used in
// FullCodeGen::SetVar(), which is architecture independent.
@@ -223,12 +208,6 @@ class RecordWriteStub: public PlatformCodeStub {
scratch1_ = Register(pool_available.PopLowestIndex());
scratch2_ = Register(pool_available.PopLowestIndex());
- // SaveCallerRegisters method needs to save caller saved register, however
- // we don't bother saving ip0 and ip1 because they are used as scratch
- // registers by the MacroAssembler.
- saved_regs_.Remove(ip0);
- saved_regs_.Remove(ip1);
-
// The scratch registers will be restored by other means so we don't need
// to save them with the other caller saved registers.
saved_regs_.Remove(scratch0_);
@@ -253,7 +232,7 @@ class RecordWriteStub: public PlatformCodeStub {
// register will need to be preserved. Can we improve this?
masm->PushCPURegList(saved_regs_);
if (mode == kSaveFPRegs) {
- masm->PushCPURegList(kCallerSavedFP);
+ masm->PushCPURegList(saved_fp_regs_);
}
}
@@ -261,7 +240,7 @@ class RecordWriteStub: public PlatformCodeStub {
// TODO(all): This can be very expensive, and it is likely that not every
// register will need to be preserved. Can we improve this?
if (mode == kSaveFPRegs) {
- masm->PopCPURegList(kCallerSavedFP);
+ masm->PopCPURegList(saved_fp_regs_);
}
masm->PopCPURegList(saved_regs_);
}
@@ -279,6 +258,7 @@ class RecordWriteStub: public PlatformCodeStub {
Register scratch1_;
Register scratch2_;
CPURegList saved_regs_;
+ CPURegList saved_fp_regs_;
// TODO(all): We should consider moving this somewhere else.
static CPURegList GetValidRegistersForAllocation() {
@@ -296,10 +276,7 @@ class RecordWriteStub: public PlatformCodeStub {
CPURegList list(CPURegister::kRegister, kXRegSizeInBits, 0, 25);
// We also remove MacroAssembler's scratch registers.
- list.Remove(ip0);
- list.Remove(ip1);
- list.Remove(x8);
- list.Remove(x9);
+ list.Remove(MacroAssembler::DefaultTmpList());
return list;
}
@@ -372,7 +349,7 @@ class RecordWriteStub: public PlatformCodeStub {
// the exit frame before doing the call with GenerateCall.
class DirectCEntryStub: public PlatformCodeStub {
public:
- DirectCEntryStub() {}
+ explicit DirectCEntryStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
void Generate(MacroAssembler* masm);
void GenerateCall(MacroAssembler* masm, Register target);
@@ -388,7 +365,8 @@ class NameDictionaryLookupStub: public PlatformCodeStub {
public:
enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
- explicit NameDictionaryLookupStub(LookupMode mode) : mode_(mode) { }
+ NameDictionaryLookupStub(Isolate* isolate, LookupMode mode)
+ : PlatformCodeStub(isolate), mode_(mode) { }
void Generate(MacroAssembler* masm);
@@ -436,7 +414,7 @@ class NameDictionaryLookupStub: public PlatformCodeStub {
class SubStringStub: public PlatformCodeStub {
public:
- SubStringStub() {}
+ explicit SubStringStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
private:
Major MajorKey() { return SubString; }
@@ -448,7 +426,7 @@ class SubStringStub: public PlatformCodeStub {
class StringCompareStub: public PlatformCodeStub {
public:
- StringCompareStub() { }
+ explicit StringCompareStub(Isolate* isolate) : PlatformCodeStub(isolate) { }
// Compares two flat ASCII strings and returns result in x0.
static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
diff --git a/deps/v8/src/arm64/codegen-arm64.cc b/deps/v8/src/arm64/codegen-arm64.cc
index 831d449862..ff06eda86a 100644
--- a/deps/v8/src/arm64/codegen-arm64.cc
+++ b/deps/v8/src/arm64/codegen-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -339,8 +316,8 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
// Non-hole double, copy value into a heap number.
Register heap_num = x5;
- __ AllocateHeapNumber(heap_num, &gc_required, x6, x4, heap_num_map);
- __ Str(x13, FieldMemOperand(heap_num, HeapNumber::kValueOffset));
+ __ AllocateHeapNumber(heap_num, &gc_required, x6, x4,
+ x13, heap_num_map);
__ Mov(x13, dst_elements);
__ Str(heap_num, MemOperand(dst_elements, kPointerSize, PostIndex));
__ RecordWrite(array, x13, heap_num, kLRHasBeenSaved, kDontSaveFPRegs,
@@ -373,14 +350,41 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
}
-bool Code::IsYoungSequence(byte* sequence) {
- return MacroAssembler::IsYoungSequence(sequence);
+CodeAgingHelper::CodeAgingHelper() {
+ ASSERT(young_sequence_.length() == kNoCodeAgeSequenceLength);
+ // The sequence of instructions that is patched out for aging code is the
+ // following boilerplate stack-building prologue that is found both in
+ // FUNCTION and OPTIMIZED_FUNCTION code:
+ PatchingAssembler patcher(young_sequence_.start(),
+ young_sequence_.length() / kInstructionSize);
+ // The young sequence is the frame setup code for FUNCTION code types. It is
+ // generated by FullCodeGenerator::Generate.
+ MacroAssembler::EmitFrameSetupForCodeAgePatching(&patcher);
+
+#ifdef DEBUG
+ const int length = kCodeAgeStubEntryOffset / kInstructionSize;
+ ASSERT(old_sequence_.length() >= kCodeAgeStubEntryOffset);
+ PatchingAssembler patcher_old(old_sequence_.start(), length);
+ MacroAssembler::EmitCodeAgeSequence(&patcher_old, NULL);
+#endif
+}
+
+
+#ifdef DEBUG
+bool CodeAgingHelper::IsOld(byte* candidate) const {
+ return memcmp(candidate, old_sequence_.start(), kCodeAgeStubEntryOffset) == 0;
+}
+#endif
+
+
+bool Code::IsYoungSequence(Isolate* isolate, byte* sequence) {
+ return MacroAssembler::IsYoungSequence(isolate, sequence);
}
-void Code::GetCodeAgeAndParity(byte* sequence, Age* age,
+void Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
MarkingParity* parity) {
- if (IsYoungSequence(sequence)) {
+ if (IsYoungSequence(isolate, sequence)) {
*age = kNoAgeCodeAge;
*parity = NO_MARKING_PARITY;
} else {
@@ -395,7 +399,8 @@ void Code::PatchPlatformCodeAge(Isolate* isolate,
byte* sequence,
Code::Age age,
MarkingParity parity) {
- PatchingAssembler patcher(sequence, kCodeAgeSequenceSize / kInstructionSize);
+ PatchingAssembler patcher(sequence,
+ kNoCodeAgeSequenceLength / kInstructionSize);
if (age == kNoAgeCodeAge) {
MacroAssembler::EmitFrameSetupForCodeAgePatching(&patcher);
} else {
diff --git a/deps/v8/src/arm64/codegen-arm64.h b/deps/v8/src/arm64/codegen-arm64.h
index 4d8a9a85a7..bb42bf8d31 100644
--- a/deps/v8/src/arm64/codegen-arm64.h
+++ b/deps/v8/src/arm64/codegen-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_CODEGEN_ARM64_H_
#define V8_ARM64_CODEGEN_ARM64_H_
diff --git a/deps/v8/src/arm64/constants-arm64.h b/deps/v8/src/arm64/constants-arm64.h
index 8866e23cf1..7ee22760d8 100644
--- a/deps/v8/src/arm64/constants-arm64.h
+++ b/deps/v8/src/arm64/constants-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_CONSTANTS_ARM64_H_
#define V8_ARM64_CONSTANTS_ARM64_H_
@@ -112,6 +89,8 @@ const unsigned kZeroRegCode = 31;
const unsigned kJSSPCode = 28;
const unsigned kSPRegInternalCode = 63;
const unsigned kRegCodeMask = 0x1f;
+const unsigned kShiftAmountWRegMask = 0x1f;
+const unsigned kShiftAmountXRegMask = 0x3f;
// Standard machine types defined by AAPCS64.
const unsigned kByteSize = 8;
const unsigned kByteSizeInBytes = kByteSize >> 3;
@@ -130,6 +109,7 @@ const unsigned kQuadWordSizeInBytes = kQuadWordSize >> 3;
// AArch64 floating-point specifics. These match IEEE-754.
const unsigned kDoubleMantissaBits = 52;
const unsigned kDoubleExponentBits = 11;
+const unsigned kDoubleExponentBias = 1023;
const unsigned kFloatMantissaBits = 23;
const unsigned kFloatExponentBits = 8;
@@ -262,8 +242,8 @@ const int ImmPCRel_mask = ImmPCRelLo_mask | ImmPCRelHi_mask;
enum Condition {
eq = 0,
ne = 1,
- hs = 2,
- lo = 3,
+ hs = 2, cs = hs,
+ lo = 3, cc = lo,
mi = 4,
pl = 5,
vs = 6,
diff --git a/deps/v8/src/arm64/cpu-arm64.cc b/deps/v8/src/arm64/cpu-arm64.cc
index b8899adb37..0e1ed91be4 100644
--- a/deps/v8/src/arm64/cpu-arm64.cc
+++ b/deps/v8/src/arm64/cpu-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// CPU specific code for arm independent of OS goes here.
@@ -41,28 +18,36 @@ namespace internal {
bool CpuFeatures::initialized_ = false;
#endif
unsigned CpuFeatures::supported_ = 0;
-unsigned CpuFeatures::found_by_runtime_probing_only_ = 0;
unsigned CpuFeatures::cross_compile_ = 0;
-// Initialise to smallest possible cache size.
-unsigned CpuFeatures::dcache_line_size_ = 1;
-unsigned CpuFeatures::icache_line_size_ = 1;
+class CacheLineSizes {
+ public:
+ CacheLineSizes() {
+#ifdef USE_SIMULATOR
+ cache_type_register_ = 0;
+#else
+ // Copy the content of the cache type register to a core register.
+ __asm__ __volatile__ ("mrs %[ctr], ctr_el0" // NOLINT
+ : [ctr] "=r" (cache_type_register_));
+#endif
+ };
-void CPU::SetUp() {
- CpuFeatures::Probe();
-}
+ uint32_t icache_line_size() const { return ExtractCacheLineSize(0); }
+ uint32_t dcache_line_size() const { return ExtractCacheLineSize(16); }
+ private:
+ uint32_t ExtractCacheLineSize(int cache_line_size_shift) const {
+ // The cache type register holds the size of the caches as a power of two.
+ return 1 << ((cache_type_register_ >> cache_line_size_shift) & 0xf);
+ }
-bool CPU::SupportsCrankshaft() {
- return true;
-}
+ uint32_t cache_type_register_;
+};
void CPU::FlushICache(void* address, size_t length) {
- if (length == 0) {
- return;
- }
+ if (length == 0) return;
#ifdef USE_SIMULATOR
// TODO(all): consider doing some cache simulation to ensure every address
@@ -76,8 +61,9 @@ void CPU::FlushICache(void* address, size_t length) {
uintptr_t start = reinterpret_cast<uintptr_t>(address);
// Sizes will be used to generate a mask big enough to cover a pointer.
- uintptr_t dsize = static_cast<uintptr_t>(CpuFeatures::dcache_line_size());
- uintptr_t isize = static_cast<uintptr_t>(CpuFeatures::icache_line_size());
+ CacheLineSizes sizes;
+ uintptr_t dsize = sizes.dcache_line_size();
+ uintptr_t isize = sizes.icache_line_size();
// Cache line sizes are always a power of 2.
ASSERT(CountSetBits(dsize, 64) == 1);
ASSERT(CountSetBits(isize, 64) == 1);
@@ -139,26 +125,7 @@ void CPU::FlushICache(void* address, size_t length) {
}
-void CpuFeatures::Probe() {
- // Compute I and D cache line size. The cache type register holds
- // information about the caches.
- uint32_t cache_type_register = GetCacheType();
-
- static const int kDCacheLineSizeShift = 16;
- static const int kICacheLineSizeShift = 0;
- static const uint32_t kDCacheLineSizeMask = 0xf << kDCacheLineSizeShift;
- static const uint32_t kICacheLineSizeMask = 0xf << kICacheLineSizeShift;
-
- // The cache type register holds the size of the I and D caches as a power of
- // two.
- uint32_t dcache_line_size_power_of_two =
- (cache_type_register & kDCacheLineSizeMask) >> kDCacheLineSizeShift;
- uint32_t icache_line_size_power_of_two =
- (cache_type_register & kICacheLineSizeMask) >> kICacheLineSizeShift;
-
- dcache_line_size_ = 1 << dcache_line_size_power_of_two;
- icache_line_size_ = 1 << icache_line_size_power_of_two;
-
+void CpuFeatures::Probe(bool serializer_enabled) {
// AArch64 has no configuration options, no further probing is required.
supported_ = 0;
@@ -168,32 +135,6 @@ void CpuFeatures::Probe() {
}
-unsigned CpuFeatures::dcache_line_size() {
- ASSERT(initialized_);
- return dcache_line_size_;
-}
-
-
-unsigned CpuFeatures::icache_line_size() {
- ASSERT(initialized_);
- return icache_line_size_;
-}
-
-
-uint32_t CpuFeatures::GetCacheType() {
-#ifdef USE_SIMULATOR
- // This will lead to a cache with 1 byte long lines, which is fine since the
- // simulator will not need this information.
- return 0;
-#else
- uint32_t cache_type_register;
- // Copy the content of the cache type register to a core register.
- __asm__ __volatile__ ("mrs %[ctr], ctr_el0" // NOLINT
- : [ctr] "=r" (cache_type_register));
- return cache_type_register;
-#endif
-}
-
} } // namespace v8::internal
#endif // V8_TARGET_ARCH_ARM64
diff --git a/deps/v8/src/arm64/cpu-arm64.h b/deps/v8/src/arm64/cpu-arm64.h
index ddec72d8f6..0b7a7d7f1f 100644
--- a/deps/v8/src/arm64/cpu-arm64.h
+++ b/deps/v8/src/arm64/cpu-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_CPU_ARM64_H_
#define V8_ARM64_CPU_ARM64_H_
@@ -42,7 +19,7 @@ class CpuFeatures : public AllStatic {
public:
// Detect features of the target CPU. Set safe defaults if the serializer
// is enabled (snapshots must be portable).
- static void Probe();
+ static void Probe(bool serializer_enabled);
// Check whether a feature is supported by the target CPU.
static bool IsSupported(CpuFeature f) {
@@ -51,15 +28,9 @@ class CpuFeatures : public AllStatic {
return false;
};
- static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
- ASSERT(initialized_);
- // There are no optional features for ARM64.
- return false;
- }
-
- static bool IsSafeForSnapshot(CpuFeature f) {
- return (IsSupported(f) &&
- (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
+ // There are no optional features for ARM64.
+ static bool IsSafeForSnapshot(Isolate* isolate, CpuFeature f) {
+ return IsSupported(f);
}
// I and D cache line size in bytes.
@@ -81,21 +52,14 @@ class CpuFeatures : public AllStatic {
return true;
}
- private:
- // Return the content of the cache type register.
- static uint32_t GetCacheType();
-
- // I and D cache line size in bytes.
- static unsigned icache_line_size_;
- static unsigned dcache_line_size_;
+ static bool SupportsCrankshaft() { return true; }
+ private:
#ifdef DEBUG
static bool initialized_;
#endif
// This isn't used (and is always 0), but it is required by V8.
- static unsigned found_by_runtime_probing_only_;
-
static unsigned cross_compile_;
friend class PlatformFeatureScope;
diff --git a/deps/v8/src/arm64/debug-arm64.cc b/deps/v8/src/arm64/debug-arm64.cc
index 716337f051..6b18967821 100644
--- a/deps/v8/src/arm64/debug-arm64.cc
+++ b/deps/v8/src/arm64/debug-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -38,8 +15,6 @@ namespace internal {
#define __ ACCESS_MASM(masm)
-
-#ifdef ENABLE_DEBUGGER_SUPPORT
bool BreakLocationIterator::IsDebugBreakAtReturn() {
return Debug::IsDebugBreakAtReturn(rinfo());
}
@@ -67,7 +42,7 @@ void BreakLocationIterator::SetDebugBreakAtReturn() {
STATIC_ASSERT(Assembler::kJSRetSequenceInstructions >= 5);
PatchingAssembler patcher(reinterpret_cast<Instruction*>(rinfo()->pc()), 5);
byte* entry =
- debug_info_->GetIsolate()->debug()->debug_break_return()->entry();
+ debug_info_->GetIsolate()->builtins()->Return_DebugBreak()->entry();
// The first instruction of a patched return sequence must be a load literal
// loading the address of the debug break return code.
@@ -126,7 +101,7 @@ void BreakLocationIterator::SetDebugBreakAtSlot() {
STATIC_ASSERT(Assembler::kDebugBreakSlotInstructions >= 4);
PatchingAssembler patcher(reinterpret_cast<Instruction*>(rinfo()->pc()), 4);
byte* entry =
- debug_info_->GetIsolate()->debug()->debug_break_slot()->entry();
+ debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry();
// The first instruction of a patched debug break slot must be a load literal
// loading the address of the debug break slot code.
@@ -204,7 +179,7 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
__ Mov(x0, 0); // No arguments.
__ Mov(x1, ExternalReference::debug_break(masm->isolate()));
- CEntryStub stub(1);
+ CEntryStub stub(masm->isolate(), 1);
__ CallStub(&stub);
// Restore the register values from the expression stack.
@@ -240,6 +215,16 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
}
+void Debug::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
+ // Register state for CallICStub
+ // ----------- S t a t e -------------
+ // -- x1 : function
+ // -- x3 : slot in feedback array
+ // -----------------------------------
+ Generate_DebugBreakCallHelper(masm, x1.Bit() | x3.Bit(), 0, x10);
+}
+
+
void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC load (from ic-arm.cc).
// ----------- S t a t e -------------
@@ -296,15 +281,6 @@ void Debug::GenerateCompareNilICDebugBreak(MacroAssembler* masm) {
}
-void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) {
- // Calling convention for IC call (from ic-arm.cc)
- // ----------- S t a t e -------------
- // -- x2 : name
- // -----------------------------------
- Generate_DebugBreakCallHelper(masm, x2.Bit(), 0, x10);
-}
-
-
void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
// In places other than IC call sites it is expected that r0 is TOS which
// is an object - this is not generally the case so this should be used with
@@ -322,17 +298,6 @@ void Debug::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
}
-void Debug::GenerateCallFunctionStubRecordDebugBreak(MacroAssembler* masm) {
- // Register state for CallFunctionStub (from code-stubs-arm64.cc).
- // ----------- S t a t e -------------
- // -- x1 : function
- // -- x2 : feedback array
- // -- x3 : slot in feedback array
- // -----------------------------------
- Generate_DebugBreakCallHelper(masm, x1.Bit() | x2.Bit() | x3.Bit(), 0, x10);
-}
-
-
void Debug::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
// Calling convention for CallConstructStub (from code-stubs-arm64.cc).
// ----------- S t a t e -------------
@@ -386,8 +351,6 @@ void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
const bool Debug::kFrameDropperSupported = false;
-#endif // ENABLE_DEBUGGER_SUPPORT
-
} } // namespace v8::internal
#endif // V8_TARGET_ARCH_ARM64
diff --git a/deps/v8/src/arm64/decoder-arm64-inl.h b/deps/v8/src/arm64/decoder-arm64-inl.h
index 94009c704d..eb791336da 100644
--- a/deps/v8/src/arm64/decoder-arm64-inl.h
+++ b/deps/v8/src/arm64/decoder-arm64-inl.h
@@ -1,29 +1,6 @@
// Copyright 2014 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_DECODER_ARM64_INL_H_
#define V8_ARM64_DECODER_ARM64_INL_H_
diff --git a/deps/v8/src/arm64/decoder-arm64.cc b/deps/v8/src/arm64/decoder-arm64.cc
index a9829f0abc..13962387dd 100644
--- a/deps/v8/src/arm64/decoder-arm64.cc
+++ b/deps/v8/src/arm64/decoder-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/arm64/decoder-arm64.h b/deps/v8/src/arm64/decoder-arm64.h
index e48f741bf5..4409421bdc 100644
--- a/deps/v8/src/arm64/decoder-arm64.h
+++ b/deps/v8/src/arm64/decoder-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_DECODER_ARM64_H_
#define V8_ARM64_DECODER_ARM64_H_
diff --git a/deps/v8/src/arm64/deoptimizer-arm64.cc b/deps/v8/src/arm64/deoptimizer-arm64.cc
index 93cb5176d2..a19e2fc9fd 100644
--- a/deps/v8/src/arm64/deoptimizer-arm64.cc
+++ b/deps/v8/src/arm64/deoptimizer-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -138,6 +115,43 @@ Code* Deoptimizer::NotifyStubFailureBuiltin() {
}
+#define __ masm->
+
+static void CopyRegisterDumpToFrame(MacroAssembler* masm,
+ Register frame,
+ CPURegList reg_list,
+ Register scratch1,
+ Register scratch2,
+ int src_offset,
+ int dst_offset) {
+ int offset0, offset1;
+ CPURegList copy_to_input = reg_list;
+ int reg_count = reg_list.Count();
+ int reg_size = reg_list.RegisterSizeInBytes();
+ for (int i = 0; i < (reg_count / 2); i++) {
+ __ PeekPair(scratch1, scratch2, src_offset + (i * reg_size * 2));
+
+ offset0 = (copy_to_input.PopLowestIndex().code() * reg_size) + dst_offset;
+ offset1 = (copy_to_input.PopLowestIndex().code() * reg_size) + dst_offset;
+
+ if ((offset0 + reg_size) == offset1) {
+ // Registers are adjacent: store in pairs.
+ __ Stp(scratch1, scratch2, MemOperand(frame, offset0));
+ } else {
+ // Registers are not adjacent: store individually.
+ __ Str(scratch1, MemOperand(frame, offset0));
+ __ Str(scratch2, MemOperand(frame, offset1));
+ }
+ }
+ if ((reg_count & 1) != 0) {
+ __ Peek(scratch1, src_offset + (reg_count - 1) * reg_size);
+ offset0 = (copy_to_input.PopLowestIndex().code() * reg_size) + dst_offset;
+ __ Str(scratch1, MemOperand(frame, offset0));
+ }
+}
+
+#undef __
+
#define __ masm()->
void Deoptimizer::EntryGenerator::Generate() {
@@ -200,25 +214,13 @@ void Deoptimizer::EntryGenerator::Generate() {
__ Ldr(x1, MemOperand(deoptimizer, Deoptimizer::input_offset()));
// Copy core registers into the input frame.
- CPURegList copy_to_input = saved_registers;
- for (int i = 0; i < saved_registers.Count(); i++) {
- // TODO(all): Look for opportunities to optimize this by using ldp/stp.
- __ Peek(x2, i * kPointerSize);
- CPURegister current_reg = copy_to_input.PopLowestIndex();
- int offset = (current_reg.code() * kPointerSize) +
- FrameDescription::registers_offset();
- __ Str(x2, MemOperand(x1, offset));
- }
+ CopyRegisterDumpToFrame(masm(), x1, saved_registers, x2, x4, 0,
+ FrameDescription::registers_offset());
// Copy FP registers to the input frame.
- for (int i = 0; i < saved_fp_registers.Count(); i++) {
- // TODO(all): Look for opportunities to optimize this by using ldp/stp.
- int dst_offset = FrameDescription::double_registers_offset() +
- (i * kDoubleSize);
- int src_offset = kFPRegistersOffset + (i * kDoubleSize);
- __ Peek(x2, src_offset);
- __ Str(x2, MemOperand(x1, dst_offset));
- }
+ CopyRegisterDumpToFrame(masm(), x1, saved_fp_registers, x2, x4,
+ kFPRegistersOffset,
+ FrameDescription::double_registers_offset());
// Remove the bailout id and the saved registers from the stack.
__ Drop(1 + (kSavedRegistersAreaSize / kXRegSize));
diff --git a/deps/v8/src/arm64/disasm-arm64.cc b/deps/v8/src/arm64/disasm-arm64.cc
index ed3e928796..e9e1decadf 100644
--- a/deps/v8/src/arm64/disasm-arm64.cc
+++ b/deps/v8/src/arm64/disasm-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <assert.h>
#include <stdio.h>
@@ -1632,10 +1609,9 @@ int Disassembler::SubstituteBranchTargetField(Instruction* instr,
offset <<= kInstructionSizeLog2;
char sign = '+';
if (offset < 0) {
- offset = -offset;
sign = '-';
}
- AppendToOutput("#%c0x%" PRIx64 " (addr %p)", sign, offset,
+ AppendToOutput("#%c0x%" PRIx64 " (addr %p)", sign, Abs(offset),
instr->InstructionAtOffset(offset), Instruction::NO_CHECK);
return 8;
}
diff --git a/deps/v8/src/arm64/disasm-arm64.h b/deps/v8/src/arm64/disasm-arm64.h
index 8c964a8905..42552a2d8b 100644
--- a/deps/v8/src/arm64/disasm-arm64.h
+++ b/deps/v8/src/arm64/disasm-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_DISASM_ARM64_H
#define V8_ARM64_DISASM_ARM64_H
diff --git a/deps/v8/src/arm64/frames-arm64.cc b/deps/v8/src/arm64/frames-arm64.cc
index 8c1bc20ac1..da638ad6e3 100644
--- a/deps/v8/src/arm64/frames-arm64.cc
+++ b/deps/v8/src/arm64/frames-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/arm64/frames-arm64.h b/deps/v8/src/arm64/frames-arm64.h
index 8b56410584..3996bd75dc 100644
--- a/deps/v8/src/arm64/frames-arm64.h
+++ b/deps/v8/src/arm64/frames-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "arm64/constants-arm64.h"
#include "arm64/assembler-arm64.h"
diff --git a/deps/v8/src/arm64/full-codegen-arm64.cc b/deps/v8/src/arm64/full-codegen-arm64.cc
index d40e74aa27..0196e69e45 100644
--- a/deps/v8/src/arm64/full-codegen-arm64.cc
+++ b/deps/v8/src/arm64/full-codegen-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -117,10 +94,14 @@ static void EmitStackCheck(MacroAssembler* masm_,
Label ok;
ASSERT(jssp.Is(__ StackPointer()));
ASSERT(scratch.Is(jssp) == (pointers == 0));
+ Heap::RootListIndex index;
if (pointers != 0) {
__ Sub(scratch, jssp, pointers * kPointerSize);
+ index = Heap::kRealStackLimitRootIndex;
+ } else {
+ index = Heap::kStackLimitRootIndex;
}
- __ CompareRoot(scratch, Heap::kStackLimitRootIndex);
+ __ CompareRoot(scratch, index);
__ B(hs, &ok);
PredictableCodeSizeScope predictable(masm_,
Assembler::kCallSizeWithRelocation);
@@ -148,8 +129,6 @@ void FullCodeGenerator::Generate() {
handler_table_ =
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
- InitializeFeedbackVector();
-
profiling_counter_ = isolate()->factory()->NewCell(
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
SetFunctionPosition(function());
@@ -237,7 +216,7 @@ void FullCodeGenerator::Generate() {
__ Push(x1, x10);
__ CallRuntime(Runtime::kHiddenNewGlobalContext, 2);
} else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
- FastNewContextStub stub(heap_slots);
+ FastNewContextStub stub(isolate(), heap_slots);
__ CallStub(&stub);
} else {
__ Push(x1);
@@ -297,7 +276,7 @@ void FullCodeGenerator::Generate() {
} else {
type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
}
- ArgumentsAccessStub stub(type);
+ ArgumentsAccessStub stub(isolate(), type);
__ CallStub(&stub);
SetVar(arguments, x0, x1, x2);
@@ -387,7 +366,12 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
Label ok;
ASSERT(back_edge_target->is_bound());
- int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
+ // We want to do a round rather than a floor of distance/kCodeSizeMultiplier
+ // to reduce the absolute error due to the integer division. To do that,
+ // we add kCodeSizeMultiplier/2 to the distance (equivalent to adding 0.5 to
+ // the result).
+ int distance =
+ masm_->SizeOfCodeGeneratedSince(back_edge_target) + kCodeSizeMultiplier / 2;
int weight = Min(kMaxBackEdgeWeight,
Max(1, distance / kCodeSizeMultiplier));
EmitProfilingCounterDecrement(weight);
@@ -430,7 +414,7 @@ void FullCodeGenerator::EmitReturnSequence() {
if (info_->ShouldSelfOptimize()) {
weight = FLAG_interrupt_budget / FLAG_self_opt_count;
} else {
- int distance = masm_->pc_offset();
+ int distance = masm_->pc_offset() + kCodeSizeMultiplier / 2;
weight = Min(kMaxBackEdgeWeight,
Max(1, distance / kCodeSizeMultiplier));
}
@@ -1195,12 +1179,8 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// We got a fixed array in register x0. Iterate through that.
__ Bind(&fixed_array);
- Handle<Object> feedback = Handle<Object>(
- Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
- isolate());
- StoreFeedbackVectorSlot(slot, feedback);
__ LoadObject(x1, FeedbackVector());
- __ Mov(x10, Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker));
+ __ Mov(x10, Operand(TypeFeedbackInfo::MegamorphicSentinel(isolate())));
__ Str(x10, FieldMemOperand(x1, FixedArray::OffsetOfElementAt(slot)));
__ Mov(x1, Smi::FromInt(1)); // Smi indicates slow check.
@@ -1359,7 +1339,9 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
!pretenure &&
scope()->is_function_scope() &&
info->num_literals() == 0) {
- FastNewClosureStub stub(info->strict_mode(), info->is_generator());
+ FastNewClosureStub stub(isolate(),
+ info->strict_mode(),
+ info->is_generator());
__ Mov(x2, Operand(info));
__ CallStub(&stub);
} else {
@@ -1672,13 +1654,13 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
int properties_count = constant_properties->length() / 2;
const int max_cloned_properties =
FastCloneShallowObjectStub::kMaximumClonedProperties;
- if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() ||
- flags != ObjectLiteral::kFastElements ||
+ if (expr->may_store_doubles() || expr->depth() > 1 ||
+ Serializer::enabled(isolate()) || flags != ObjectLiteral::kFastElements ||
properties_count > max_cloned_properties) {
__ Push(x3, x2, x1, x0);
__ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4);
} else {
- FastCloneShallowObjectStub stub(properties_count);
+ FastCloneShallowObjectStub stub(isolate(), properties_count);
__ CallStub(&stub);
}
@@ -1816,13 +1798,14 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
if (has_fast_elements && constant_elements_values->map() ==
isolate()->heap()->fixed_cow_array_map()) {
FastCloneShallowArrayStub stub(
+ isolate(),
FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS,
allocation_site_mode,
length);
__ CallStub(&stub);
__ IncrementCounter(
isolate()->counters()->cow_arrays_created_stub(), 1, x10, x11);
- } else if ((expr->depth() > 1) || Serializer::enabled() ||
+ } else if ((expr->depth() > 1) || Serializer::enabled(isolate()) ||
length > FastCloneShallowArrayStub::kMaximumClonedLength) {
__ Mov(x0, Smi::FromInt(flags));
__ Push(x3, x2, x1, x0);
@@ -1837,7 +1820,10 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
mode = FastCloneShallowArrayStub::CLONE_ELEMENTS;
}
- FastCloneShallowArrayStub stub(mode, allocation_site_mode, length);
+ FastCloneShallowArrayStub stub(isolate(),
+ mode,
+ allocation_site_mode,
+ length);
__ CallStub(&stub);
}
@@ -1869,7 +1855,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
EMIT_REMEMBERED_SET, INLINE_SMI_CHECK);
} else {
__ Mov(x3, Smi::FromInt(i));
- StoreArrayLiteralElementStub stub;
+ StoreArrayLiteralElementStub stub(isolate());
__ CallStub(&stub);
}
@@ -1886,7 +1872,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
void FullCodeGenerator::VisitAssignment(Assignment* expr) {
- ASSERT(expr->target()->IsValidLeftHandSide());
+ ASSERT(expr->target()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ Assignment");
@@ -2030,10 +2016,10 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
patch_site.EmitJumpIfSmi(x10, &both_smis);
__ Bind(&stub_call);
- BinaryOpICStub stub(op, mode);
+ BinaryOpICStub stub(isolate(), op, mode);
{
Assembler::BlockPoolsScope scope(masm_);
- CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
+ CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
}
__ B(&done);
@@ -2115,11 +2101,11 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode) {
__ Pop(x1);
- BinaryOpICStub stub(op, mode);
+ BinaryOpICStub stub(isolate(), op, mode);
JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code.
{
Assembler::BlockPoolsScope scope(masm_);
- CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
+ CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
}
context()->Plug(x0);
@@ -2127,7 +2113,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
void FullCodeGenerator::EmitAssignment(Expression* expr) {
- ASSERT(expr->IsValidLeftHandSide());
+ ASSERT(expr->IsValidReferenceExpression());
// Left-hand side can only be a property, a global or a (parameter or local)
// slot.
@@ -2333,16 +2319,15 @@ void FullCodeGenerator::CallIC(Handle<Code> code,
// Code common for calls using the IC.
-void FullCodeGenerator::EmitCallWithIC(Call* expr) {
- ASM_LOCATION("EmitCallWithIC");
-
+void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
- ZoneList<Expression*>* args = expr->arguments();
- int arg_count = args->length();
- CallFunctionFlags flags;
+ CallIC::CallType call_type = callee->IsVariableProxy()
+ ? CallIC::FUNCTION
+ : CallIC::METHOD;
+
// Get the target function.
- if (callee->IsVariableProxy()) {
+ if (call_type == CallIC::FUNCTION) {
{ StackValueContext context(this);
EmitVariableLoad(callee->AsVariableProxy());
PrepareForBailout(callee, NO_REGISTERS);
@@ -2350,7 +2335,6 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr) {
// Push undefined as receiver. This is patched in the method prologue if it
// is a sloppy mode method.
__ Push(isolate()->factory()->undefined_value());
- flags = NO_CALL_FUNCTION_FLAGS;
} else {
// Load the function from the receiver.
ASSERT(callee->IsProperty());
@@ -2360,40 +2344,19 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr) {
// Push the target function under the receiver.
__ Pop(x10);
__ Push(x0, x10);
- flags = CALL_AS_METHOD;
}
- // Load the arguments.
- { PreservePositionScope scope(masm()->positions_recorder());
- for (int i = 0; i < arg_count; i++) {
- VisitForStackValue(args->at(i));
- }
- }
-
- // Record source position for debugger.
- SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, flags);
- __ Peek(x1, (arg_count + 1) * kPointerSize);
- __ CallStub(&stub);
-
- RecordJSReturnSite(expr);
-
- // Restore context register.
- __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-
- context()->DropAndPlug(1, x0);
+ EmitCall(expr, call_type);
}
// Code common for calls using the IC.
-void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
- Expression* key) {
+void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
+ Expression* key) {
// Load the key.
VisitForAccumulatorValue(key);
Expression* callee = expr->expression();
- ZoneList<Expression*>* args = expr->arguments();
- int arg_count = args->length();
// Load the function from the receiver.
ASSERT(callee->IsProperty());
@@ -2405,28 +2368,12 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
__ Pop(x10);
__ Push(x0, x10);
- { PreservePositionScope scope(masm()->positions_recorder());
- for (int i = 0; i < arg_count; i++) {
- VisitForStackValue(args->at(i));
- }
- }
-
- // Record source position for debugger.
- SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, CALL_AS_METHOD);
- __ Peek(x1, (arg_count + 1) * kPointerSize);
- __ CallStub(&stub);
-
- RecordJSReturnSite(expr);
- // Restore context register.
- __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-
- context()->DropAndPlug(1, x0);
+ EmitCall(expr, CallIC::METHOD);
}
-void FullCodeGenerator::EmitCallWithStub(Call* expr) {
- // Code common for calls using the call stub.
+void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) {
+ // Load the arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope scope(masm()->positions_recorder());
@@ -2434,19 +2381,17 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr) {
VisitForStackValue(args->at(i));
}
}
- // Record source position for debugger.
+ // Record source position of the IC call.
SetSourcePosition(expr->position());
- Handle<Object> uninitialized =
- TypeFeedbackInfo::UninitializedSentinel(isolate());
- StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
- __ LoadObject(x2, FeedbackVector());
+ Handle<Code> ic = CallIC::initialize_stub(
+ isolate(), arg_count, call_type);
__ Mov(x3, Smi::FromInt(expr->CallFeedbackSlot()));
-
- // Record call targets in unoptimized code.
- CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
__ Peek(x1, (arg_count + 1) * kXRegSize);
- __ CallStub(&stub);
+ // Don't assign a type feedback id to the IC, since type feedback is provided
+ // by the vector above.
+ CallIC(ic);
+
RecordJSReturnSite(expr);
// Restore context register.
__ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2529,7 +2474,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
SetSourcePosition(expr->position());
// Call the evaluated function.
- CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
+ CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ Peek(x1, (arg_count + 1) * kXRegSize);
__ CallStub(&stub);
RecordJSReturnSite(expr);
@@ -2538,7 +2483,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
context()->DropAndPlug(1, x0);
} else if (call_type == Call::GLOBAL_CALL) {
- EmitCallWithIC(expr);
+ EmitCallWithLoadIC(expr);
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
// Call to a lookup slot (dynamically introduced variable).
@@ -2578,16 +2523,16 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// The receiver is either the global receiver or an object found
// by LoadContextSlot.
- EmitCallWithStub(expr);
+ EmitCall(expr);
} else if (call_type == Call::PROPERTY_CALL) {
Property* property = callee->AsProperty();
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
if (property->key()->IsPropertyName()) {
- EmitCallWithIC(expr);
+ EmitCallWithLoadIC(expr);
} else {
- EmitKeyedCallWithIC(expr, property->key());
+ EmitKeyedCallWithLoadIC(expr, property->key());
}
} else {
@@ -2599,7 +2544,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ LoadRoot(x1, Heap::kUndefinedValueRootIndex);
__ Push(x1);
// Emit function call.
- EmitCallWithStub(expr);
+ EmitCall(expr);
}
#ifdef DEBUG
@@ -2636,12 +2581,8 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
__ Peek(x1, arg_count * kXRegSize);
// Record call targets in unoptimized code.
- Handle<Object> uninitialized =
- TypeFeedbackInfo::UninitializedSentinel(isolate());
- StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
if (FLAG_pretenuring_call_new) {
- StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(),
- isolate()->factory()->NewAllocationSite());
+ EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
ASSERT(expr->AllocationSiteFeedbackSlot() ==
expr->CallNewFeedbackSlot() + 1);
}
@@ -2649,8 +2590,8 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
__ LoadObject(x2, FeedbackVector());
__ Mov(x3, Smi::FromInt(expr->CallNewFeedbackSlot()));
- CallConstructStub stub(RECORD_CALL_TARGET);
- __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
+ CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
+ __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
context()->Plug(x0);
}
@@ -3033,7 +2974,7 @@ void FullCodeGenerator::EmitArguments(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(0));
__ Mov(x1, x0);
__ Mov(x0, Smi::FromInt(info_->scope()->num_parameters()));
- ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
+ ArgumentsAccessStub stub(isolate(), ArgumentsAccessStub::READ_ELEMENT);
__ CallStub(&stub);
context()->Plug(x0);
}
@@ -3124,31 +3065,9 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
}
-void FullCodeGenerator::EmitLog(CallRuntime* expr) {
- // Conditionally generate a log call.
- // Args:
- // 0 (literal string): The type of logging (corresponds to the flags).
- // This is used to determine whether or not to generate the log call.
- // 1 (string): Format string. Access the string at argument index 2
- // with '%2s' (see Logger::LogRuntime for all the formats).
- // 2 (array): Arguments to the format string.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT_EQ(args->length(), 3);
- if (CodeGenerator::ShouldGenerateLog(isolate(), args->at(0))) {
- VisitForStackValue(args->at(1));
- VisitForStackValue(args->at(2));
- __ CallRuntime(Runtime::kHiddenLog, 2);
- }
-
- // Finally, we're expected to leave a value on the top of the stack.
- __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
- context()->Plug(x0);
-}
-
-
void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
// Load the arguments on the stack and call the stub.
- SubStringStub stub;
+ SubStringStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 3);
VisitForStackValue(args->at(0));
@@ -3161,7 +3080,7 @@ void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) {
// Load the arguments on the stack and call the stub.
- RegExpExecStub stub;
+ RegExpExecStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 4);
VisitForStackValue(args->at(0));
@@ -3303,7 +3222,7 @@ void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
ASSERT(args->length() == 2);
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
- MathPowStub stub(MathPowStub::ON_STACK);
+ MathPowStub stub(isolate(), MathPowStub::ON_STACK);
__ CallStub(&stub);
context()->Plug(x0);
}
@@ -3345,7 +3264,7 @@ void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
// Load the argument into x0 and call the stub.
VisitForAccumulatorValue(args->at(0));
- NumberToStringStub stub;
+ NumberToStringStub stub(isolate());
__ CallStub(&stub);
context()->Plug(x0);
}
@@ -3473,7 +3392,7 @@ void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(1));
__ Pop(x1);
- StringAddStub stub(STRING_ADD_CHECK_BOTH, NOT_TENURED);
+ StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED);
__ CallStub(&stub);
context()->Plug(x0);
@@ -3486,32 +3405,12 @@ void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
- StringCompareStub stub;
+ StringCompareStub stub(isolate());
__ CallStub(&stub);
context()->Plug(x0);
}
-void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_log, 1);
- context()->Plug(x0);
-}
-
-
-void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_sqrt, 1);
- context()->Plug(x0);
-}
-
-
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ASM_LOCATION("FullCodeGenerator::EmitCallFunction");
ZoneList<Expression*>* args = expr->arguments();
@@ -3545,7 +3444,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
- RegExpConstructResultStub stub;
+ RegExpConstructResultStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 3);
VisitForStackValue(args->at(0));
@@ -3889,7 +3788,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
// Record source position of the IC call.
SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
+ CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ Peek(x1, (arg_count + 1) * kPointerSize);
__ CallStub(&stub);
@@ -4021,7 +3920,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
- ASSERT(expr->expression()->IsValidLeftHandSide());
+ ASSERT(expr->expression()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ CountOperation");
SetSourcePosition(expr->position());
@@ -4107,7 +4006,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ B(&stub_call);
__ Bind(&slow);
}
- ToNumberStub convert_stub;
+ ToNumberStub convert_stub(isolate());
__ CallStub(&convert_stub);
// Save result for postfix expressions.
@@ -4139,8 +4038,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
{
Assembler::BlockPoolsScope scope(masm_);
- BinaryOpICStub stub(Token::ADD, NO_OVERWRITE);
- CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId());
+ BinaryOpICStub stub(isolate(), Token::ADD, NO_OVERWRITE);
+ CallIC(stub.GetCode(), expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
}
__ Bind(&done);
@@ -4254,13 +4153,14 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
}
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
- if (check->Equals(isolate()->heap()->number_string())) {
+ Factory* factory = isolate()->factory();
+ if (String::Equals(check, factory->number_string())) {
ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof number_string");
__ JumpIfSmi(x0, if_true);
__ Ldr(x0, FieldMemOperand(x0, HeapObject::kMapOffset));
__ CompareRoot(x0, Heap::kHeapNumberMapRootIndex);
Split(eq, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->string_string())) {
+ } else if (String::Equals(check, factory->string_string())) {
ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof string_string");
__ JumpIfSmi(x0, if_false);
// Check for undetectable objects => false.
@@ -4268,22 +4168,22 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ Ldrb(x1, FieldMemOperand(x0, Map::kBitFieldOffset));
__ TestAndSplit(x1, 1 << Map::kIsUndetectable, if_true, if_false,
fall_through);
- } else if (check->Equals(isolate()->heap()->symbol_string())) {
+ } else if (String::Equals(check, factory->symbol_string())) {
ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof symbol_string");
__ JumpIfSmi(x0, if_false);
__ CompareObjectType(x0, x0, x1, SYMBOL_TYPE);
Split(eq, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->boolean_string())) {
+ } else if (String::Equals(check, factory->boolean_string())) {
ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof boolean_string");
__ JumpIfRoot(x0, Heap::kTrueValueRootIndex, if_true);
__ CompareRoot(x0, Heap::kFalseValueRootIndex);
Split(eq, if_true, if_false, fall_through);
} else if (FLAG_harmony_typeof &&
- check->Equals(isolate()->heap()->null_string())) {
+ String::Equals(check, factory->null_string())) {
ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof null_string");
__ CompareRoot(x0, Heap::kNullValueRootIndex);
Split(eq, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->undefined_string())) {
+ } else if (String::Equals(check, factory->undefined_string())) {
ASM_LOCATION(
"FullCodeGenerator::EmitLiteralCompareTypeof undefined_string");
__ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, if_true);
@@ -4293,7 +4193,7 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ Ldrb(x1, FieldMemOperand(x0, Map::kBitFieldOffset));
__ TestAndSplit(x1, 1 << Map::kIsUndetectable, if_false, if_true,
fall_through);
- } else if (check->Equals(isolate()->heap()->function_string())) {
+ } else if (String::Equals(check, factory->function_string())) {
ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof function_string");
__ JumpIfSmi(x0, if_false);
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
@@ -4301,7 +4201,7 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ CompareAndSplit(x11, JS_FUNCTION_PROXY_TYPE, eq, if_true, if_false,
fall_through);
- } else if (check->Equals(isolate()->heap()->object_string())) {
+ } else if (String::Equals(check, factory->object_string())) {
ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof object_string");
__ JumpIfSmi(x0, if_false);
if (!FLAG_harmony_typeof) {
@@ -4360,7 +4260,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
case Token::INSTANCEOF: {
VisitForStackValue(expr->right());
- InstanceofStub stub(InstanceofStub::kNoFlags);
+ InstanceofStub stub(isolate(), InstanceofStub::kNoFlags);
__ CallStub(&stub);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
// The stub returns 0 for true.
@@ -4568,7 +4468,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
CallIC(ic, TypeFeedbackId::None());
__ Mov(x1, x0);
__ Poke(x1, 2 * kPointerSize);
- CallFunctionStub stub(1, CALL_AS_METHOD);
+ CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
__ CallStub(&stub);
__ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -4721,7 +4621,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
Label gc_required;
Label allocated;
- Handle<Map> map(isolate()->native_context()->generator_result_map());
+ Handle<Map> map(isolate()->native_context()->iterator_result_map());
// Allocate and populate an object with this form: { value: VAL, done: DONE }
@@ -4740,22 +4640,23 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
Register result_value = x2;
Register boolean_done = x3;
Register empty_fixed_array = x4;
+ Register untagged_result = x5;
__ Mov(map_reg, Operand(map));
__ Pop(result_value);
__ Mov(boolean_done, Operand(isolate()->factory()->ToBoolean(done)));
__ Mov(empty_fixed_array, Operand(isolate()->factory()->empty_fixed_array()));
ASSERT_EQ(map->instance_size(), 5 * kPointerSize);
- // TODO(jbramley): Use Stp if possible.
- __ Str(map_reg, FieldMemOperand(result, HeapObject::kMapOffset));
- __ Str(empty_fixed_array,
- FieldMemOperand(result, JSObject::kPropertiesOffset));
- __ Str(empty_fixed_array, FieldMemOperand(result, JSObject::kElementsOffset));
- __ Str(result_value,
- FieldMemOperand(result,
- JSGeneratorObject::kResultValuePropertyOffset));
- __ Str(boolean_done,
- FieldMemOperand(result,
- JSGeneratorObject::kResultDonePropertyOffset));
+ STATIC_ASSERT(JSObject::kPropertiesOffset + kPointerSize ==
+ JSObject::kElementsOffset);
+ STATIC_ASSERT(JSGeneratorObject::kResultValuePropertyOffset + kPointerSize ==
+ JSGeneratorObject::kResultDonePropertyOffset);
+ __ ObjectUntag(untagged_result, result);
+ __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset));
+ __ Stp(empty_fixed_array, empty_fixed_array,
+ MemOperand(untagged_result, JSObject::kPropertiesOffset));
+ __ Stp(result_value, boolean_done,
+ MemOperand(untagged_result,
+ JSGeneratorObject::kResultValuePropertyOffset));
// Only the value field needs a write barrier, as the other values are in the
// root set.
@@ -4835,8 +4736,9 @@ void FullCodeGenerator::EnterFinallyBlock() {
ExternalReference has_pending_message =
ExternalReference::address_of_has_pending_message(isolate());
+ STATIC_ASSERT(sizeof(bool) == 1); // NOLINT(runtime/sizeof)
__ Mov(x11, has_pending_message);
- __ Ldr(x11, MemOperand(x11));
+ __ Ldrb(x11, MemOperand(x11));
__ SmiTag(x11);
__ Push(x10, x11);
@@ -4864,7 +4766,8 @@ void FullCodeGenerator::ExitFinallyBlock() {
ExternalReference has_pending_message =
ExternalReference::address_of_has_pending_message(isolate());
__ Mov(x13, has_pending_message);
- __ Str(x11, MemOperand(x13));
+ STATIC_ASSERT(sizeof(bool) == 1); // NOLINT(runtime/sizeof)
+ __ Strb(x11, MemOperand(x13));
ExternalReference pending_message_obj =
ExternalReference::address_of_pending_message_obj(isolate());
diff --git a/deps/v8/src/arm64/ic-arm64.cc b/deps/v8/src/arm64/ic-arm64.cc
index 5fb7d633fd..c09b847ba5 100644
--- a/deps/v8/src/arm64/ic-arm64.cc
+++ b/deps/v8/src/arm64/ic-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -1044,7 +1021,6 @@ static void KeyedStoreGenerateGenericHelper(
elements,
x10,
d0,
- d1,
&transition_double_elements);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
diff --git a/deps/v8/src/arm64/instructions-arm64.cc b/deps/v8/src/arm64/instructions-arm64.cc
index 4d1428a150..2996fc94c7 100644
--- a/deps/v8/src/arm64/instructions-arm64.cc
+++ b/deps/v8/src/arm64/instructions-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -254,11 +231,18 @@ void Instruction::SetImmPCOffsetTarget(Instruction* target) {
void Instruction::SetPCRelImmTarget(Instruction* target) {
// ADRP is not supported, so 'this' must point to an ADR instruction.
- ASSERT(Mask(PCRelAddressingMask) == ADR);
+ ASSERT(IsAdr());
- Instr imm = Assembler::ImmPCRelAddress(DistanceTo(target));
-
- SetInstructionBits(Mask(~ImmPCRel_mask) | imm);
+ int target_offset = DistanceTo(target);
+ Instr imm;
+ if (Instruction::IsValidPCRelOffset(target_offset)) {
+ imm = Assembler::ImmPCRelAddress(target_offset);
+ SetInstructionBits(Mask(~ImmPCRel_mask) | imm);
+ } else {
+ PatchingAssembler patcher(this,
+ PatchingAssembler::kAdrFarPatchableNInstrs);
+ patcher.PatchAdrFar(target);
+ }
}
diff --git a/deps/v8/src/arm64/instructions-arm64.h b/deps/v8/src/arm64/instructions-arm64.h
index ab64cb2bf0..968ddace04 100644
--- a/deps/v8/src/arm64/instructions-arm64.h
+++ b/deps/v8/src/arm64/instructions-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_INSTRUCTIONS_ARM64_H_
#define V8_ARM64_INSTRUCTIONS_ARM64_H_
@@ -160,9 +137,10 @@ class Instruction {
// ImmPCRel is a compound field (not present in INSTRUCTION_FIELDS_LIST),
// formed from ImmPCRelLo and ImmPCRelHi.
int ImmPCRel() const {
+ ASSERT(IsPCRelAddressing());
int const offset = ((ImmPCRelHi() << ImmPCRelLo_width) | ImmPCRelLo());
int const width = ImmPCRelLo_width + ImmPCRelHi_width;
- return signed_bitextract_32(width-1, 0, offset);
+ return signed_bitextract_32(width - 1, 0, offset);
}
uint64_t ImmLogical();
@@ -191,6 +169,10 @@ class Instruction {
return Mask(TestBranchFMask) == TestBranchFixed;
}
+ bool IsImmBranch() const {
+ return BranchType() != UnknownBranchType;
+ }
+
bool IsLdrLiteral() const {
return Mask(LoadLiteralFMask) == LoadLiteralFixed;
}
@@ -203,6 +185,10 @@ class Instruction {
return Mask(PCRelAddressingFMask) == PCRelAddressingFixed;
}
+ bool IsAdr() const {
+ return Mask(PCRelAddressingMask) == ADR;
+ }
+
bool IsLogicalImmediate() const {
return Mask(LogicalImmediateFMask) == LogicalImmediateFixed;
}
@@ -211,6 +197,10 @@ class Instruction {
return Mask(AddSubImmediateFMask) == AddSubImmediateFixed;
}
+ bool IsAddSubShifted() const {
+ return Mask(AddSubShiftedFMask) == AddSubShiftedFixed;
+ }
+
bool IsAddSubExtended() const {
return Mask(AddSubExtendedFMask) == AddSubExtendedFixed;
}
@@ -387,6 +377,10 @@ class Instruction {
}
+ static const int ImmPCRelRangeBitwidth = 21;
+ static bool IsValidPCRelOffset(int offset) {
+ return is_int21(offset);
+ }
void SetPCRelImmTarget(Instruction* target);
void SetBranchImmTarget(Instruction* target);
};
diff --git a/deps/v8/src/arm64/instrument-arm64.cc b/deps/v8/src/arm64/instrument-arm64.cc
index 6744707fde..a6fe1234b0 100644
--- a/deps/v8/src/arm64/instrument-arm64.cc
+++ b/deps/v8/src/arm64/instrument-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "arm64/instrument-arm64.h"
diff --git a/deps/v8/src/arm64/instrument-arm64.h b/deps/v8/src/arm64/instrument-arm64.h
index 996cc07acb..2d41b58574 100644
--- a/deps/v8/src/arm64/instrument-arm64.h
+++ b/deps/v8/src/arm64/instrument-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_INSTRUMENT_ARM64_H_
#define V8_ARM64_INSTRUMENT_ARM64_H_
diff --git a/deps/v8/src/arm64/lithium-arm64.cc b/deps/v8/src/arm64/lithium-arm64.cc
index 60bf51ebbd..2411b7074d 100644
--- a/deps/v8/src/arm64/lithium-arm64.cc
+++ b/deps/v8/src/arm64/lithium-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -515,6 +492,8 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
!hinstr->HasObservableSideEffects();
if (needs_environment && !instr->HasEnvironment()) {
instr = AssignEnvironment(instr);
+ // We can't really figure out if the environment is needed or not.
+ instr->environment()->set_has_been_used();
}
return instr;
@@ -541,6 +520,19 @@ LUnallocated* LChunkBuilder::TempRegister() {
}
+LUnallocated* LChunkBuilder::TempDoubleRegister() {
+ LUnallocated* operand =
+ new(zone()) LUnallocated(LUnallocated::MUST_HAVE_DOUBLE_REGISTER);
+ int vreg = allocator_->GetVirtualRegister();
+ if (!allocator_->AllocationOk()) {
+ Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister);
+ vreg = 0;
+ }
+ operand->set_virtual_register(vreg);
+ return operand;
+}
+
+
int LPlatformChunk::GetNextSpillIndex() {
return spill_slot_count_++;
}
@@ -702,7 +694,8 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
// the it was just a plain use), so it is free to move the split child into
// the same register that is used for the use-at-start.
// See https://code.google.com/p/chromium/issues/detail?id=201590
- if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) {
+ if (!(instr->ClobbersRegisters() &&
+ instr->ClobbersDoubleRegisters(isolate()))) {
int fixed = 0;
int used_at_start = 0;
for (UseIterator it(instr); !it.Done(); it.Advance()) {
@@ -846,6 +839,12 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
if (instr->representation().IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
+
+ LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr);
+ if (shifted_operation != NULL) {
+ return shifted_operation;
+ }
+
LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
LOperand* right =
UseRegisterOrConstantAtStart(instr->BetterRightOperand());
@@ -926,6 +925,11 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
ASSERT(instr->right()->representation().Equals(instr->representation()));
ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32));
+ LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr);
+ if (shifted_operation != NULL) {
+ return shifted_operation;
+ }
+
LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
LOperand* right =
UseRegisterOrConstantAtStart(instr->BetterRightOperand());
@@ -947,9 +951,16 @@ LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
- LOperand* value = UseRegisterOrConstantAtStart(instr->index());
- LOperand* length = UseRegister(instr->length());
- return AssignEnvironment(new(zone()) LBoundsCheck(value, length));
+ if (!FLAG_debug_code && instr->skip_check()) return NULL;
+ LOperand* index = UseRegisterOrConstantAtStart(instr->index());
+ LOperand* length = !index->IsConstantOperand()
+ ? UseRegisterOrConstantAtStart(instr->length())
+ : UseRegisterAtStart(instr->length());
+ LInstruction* result = new(zone()) LBoundsCheck(index, length);
+ if (!FLAG_debug_code || !instr->skip_check()) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -1074,63 +1085,59 @@ LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
LInstruction* LChunkBuilder::DoChange(HChange* instr) {
Representation from = instr->from();
Representation to = instr->to();
-
+ HValue* val = instr->value();
if (from.IsSmi()) {
if (to.IsTagged()) {
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
return DefineSameAsFirst(new(zone()) LDummyUse(value));
}
from = Representation::Tagged();
}
-
if (from.IsTagged()) {
if (to.IsDouble()) {
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
LOperand* temp = TempRegister();
- LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp);
- return AssignEnvironment(DefineAsRegister(res));
+ LInstruction* result =
+ DefineAsRegister(new(zone()) LNumberUntagD(value, temp));
+ if (!val->representation().IsSmi()) result = AssignEnvironment(result);
+ return result;
} else if (to.IsSmi()) {
- LOperand* value = UseRegister(instr->value());
- if (instr->value()->type().IsSmi()) {
+ LOperand* value = UseRegister(val);
+ if (val->type().IsSmi()) {
return DefineSameAsFirst(new(zone()) LDummyUse(value));
}
return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
} else {
ASSERT(to.IsInteger32());
- LInstruction* res = NULL;
-
- if (instr->value()->type().IsSmi() ||
- instr->value()->representation().IsSmi()) {
- LOperand* value = UseRegisterAtStart(instr->value());
- res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
+ if (val->type().IsSmi() || val->representation().IsSmi()) {
+ LOperand* value = UseRegisterAtStart(val);
+ return DefineAsRegister(new(zone()) LSmiUntag(value, false));
} else {
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
LOperand* temp1 = TempRegister();
- LOperand* temp2 = instr->CanTruncateToInt32() ? NULL : FixedTemp(d24);
- res = DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2));
- res = AssignEnvironment(res);
+ LOperand* temp2 = instr->CanTruncateToInt32()
+ ? NULL : TempDoubleRegister();
+ LInstruction* result =
+ DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2));
+ if (!val->representation().IsSmi()) result = AssignEnvironment(result);
+ return result;
}
-
- return res;
}
} else if (from.IsDouble()) {
if (to.IsTagged()) {
info()->MarkAsDeferredCalling();
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister();
-
LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2);
return AssignPointerMap(DefineAsRegister(result));
} else {
ASSERT(to.IsSmi() || to.IsInteger32());
- LOperand* value = UseRegister(instr->value());
-
if (instr->CanTruncateToInt32()) {
- LTruncateDoubleToIntOrSmi* result =
- new(zone()) LTruncateDoubleToIntOrSmi(value);
- return DefineAsRegister(result);
+ LOperand* value = UseRegister(val);
+ return DefineAsRegister(new(zone()) LTruncateDoubleToIntOrSmi(value));
} else {
+ LOperand* value = UseRegister(val);
LDoubleToIntOrSmi* result = new(zone()) LDoubleToIntOrSmi(value);
return AssignEnvironment(DefineAsRegister(result));
}
@@ -1138,37 +1145,35 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
} else if (from.IsInteger32()) {
info()->MarkAsDeferredCalling();
if (to.IsTagged()) {
- if (instr->value()->CheckFlag(HInstruction::kUint32)) {
- LOperand* value = UseRegister(instr->value());
- LNumberTagU* result = new(zone()) LNumberTagU(value,
- TempRegister(),
- TempRegister());
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ if (val->CheckFlag(HInstruction::kUint32)) {
+ LOperand* value = UseRegister(val);
+ LNumberTagU* result =
+ new(zone()) LNumberTagU(value, TempRegister(), TempRegister());
+ return AssignPointerMap(DefineAsRegister(result));
} else {
STATIC_ASSERT((kMinInt == Smi::kMinValue) &&
(kMaxInt == Smi::kMaxValue));
- LOperand* value = UseRegisterAtStart(instr->value());
+ LOperand* value = UseRegisterAtStart(val);
return DefineAsRegister(new(zone()) LSmiTag(value));
}
} else if (to.IsSmi()) {
- LOperand* value = UseRegisterAtStart(instr->value());
+ LOperand* value = UseRegisterAtStart(val);
LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
- if (instr->value()->CheckFlag(HInstruction::kUint32)) {
+ if (val->CheckFlag(HInstruction::kUint32)) {
result = AssignEnvironment(result);
}
return result;
} else {
ASSERT(to.IsDouble());
- if (instr->value()->CheckFlag(HInstruction::kUint32)) {
+ if (val->CheckFlag(HInstruction::kUint32)) {
return DefineAsRegister(
- new(zone()) LUint32ToDouble(UseRegisterAtStart(instr->value())));
+ new(zone()) LUint32ToDouble(UseRegisterAtStart(val)));
} else {
return DefineAsRegister(
- new(zone()) LInteger32ToDouble(UseRegisterAtStart(instr->value())));
+ new(zone()) LInteger32ToDouble(UseRegisterAtStart(val)));
}
}
}
-
UNREACHABLE();
return NULL;
}
@@ -1189,27 +1194,23 @@ LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
- if (instr->CanOmitMapChecks()) {
- // LCheckMaps does nothing in this case.
- return new(zone()) LCheckMaps(NULL);
- } else {
- LOperand* value = UseRegisterAtStart(instr->value());
- LOperand* temp = TempRegister();
-
- if (instr->has_migration_target()) {
- info()->MarkAsDeferredCalling();
- LInstruction* result = new(zone()) LCheckMaps(value, temp);
- return AssignPointerMap(AssignEnvironment(result));
- } else {
- return AssignEnvironment(new(zone()) LCheckMaps(value, temp));
- }
+ if (instr->IsStabilityCheck()) return new(zone()) LCheckMaps;
+ LOperand* value = UseRegisterAtStart(instr->value());
+ LOperand* temp = TempRegister();
+ LInstruction* result = AssignEnvironment(new(zone()) LCheckMaps(value, temp));
+ if (instr->HasMigrationTarget()) {
+ info()->MarkAsDeferredCalling();
+ result = AssignPointerMap(result);
}
+ return result;
}
LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
LOperand* value = UseRegisterAtStart(instr->value());
- return AssignEnvironment(new(zone()) LCheckNonSmi(value));
+ LInstruction* result = new(zone()) LCheckNonSmi(value);
+ if (!instr->value()->IsHeapObject()) result = AssignEnvironment(result);
+ return result;
}
@@ -1232,7 +1233,7 @@ LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
return AssignEnvironment(
DefineAsRegister(new(zone()) LClampTToUint8(reg,
TempRegister(),
- FixedTemp(d24))));
+ TempDoubleRegister())));
}
}
@@ -1249,8 +1250,9 @@ LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
LInstruction* LChunkBuilder::DoCompareNumericAndBranch(
HCompareNumericAndBranch* instr) {
+ LInstruction* goto_instr = CheckElideControlInstruction(instr);
+ if (goto_instr != NULL) return goto_instr;
Representation r = instr->representation();
-
if (r.IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().Equals(r));
ASSERT(instr->right()->representation().Equals(r));
@@ -1418,8 +1420,12 @@ LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
LOperand* divisor = UseRegister(instr->right());
LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)
? NULL : TempRegister();
- LDivI* div = new(zone()) LDivI(dividend, divisor, temp);
- return AssignEnvironment(DefineAsRegister(div));
+ LInstruction* result =
+ DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp));
+ if (!instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -1447,6 +1453,7 @@ LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) {
LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
HEnvironment* outer = current_block_->last_environment();
+ outer->set_ast_id(instr->ReturnId());
HConstant* undefined = graph()->GetConstantUndefined();
HEnvironment* inner = outer->CopyForInlining(instr->closure(),
instr->arguments_count(),
@@ -1622,7 +1629,10 @@ LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
LOperand* context = UseRegisterAtStart(instr->value());
LInstruction* result =
DefineAsRegister(new(zone()) LLoadContextSlot(context));
- return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
+ if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -1656,7 +1666,7 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
ASSERT(instr->key()->representation().IsSmiOrInteger32());
ElementsKind elements_kind = instr->elements_kind();
LOperand* elements = UseRegister(instr->elements());
- LOperand* key = UseRegisterOrConstantAtStart(instr->key());
+ LOperand* key = UseRegisterOrConstant(instr->key());
if (!instr->is_typed_elements()) {
if (instr->representation().IsDouble()) {
@@ -1687,17 +1697,14 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
IsDoubleOrFloatElementsKind(instr->elements_kind())));
LOperand* temp = instr->key()->IsConstant() ? NULL : TempRegister();
- LLoadKeyedExternal* result =
- new(zone()) LLoadKeyedExternal(elements, key, temp);
- // An unsigned int array load might overflow and cause a deopt. Make sure it
- // has an environment.
- if (instr->RequiresHoleCheck() ||
- elements_kind == EXTERNAL_UINT32_ELEMENTS ||
- elements_kind == UINT32_ELEMENTS) {
- return AssignEnvironment(DefineAsRegister(result));
- } else {
- return DefineAsRegister(result);
+ LInstruction* result = DefineAsRegister(
+ new(zone()) LLoadKeyedExternal(elements, key, temp));
+ if ((elements_kind == EXTERNAL_UINT32_ELEMENTS ||
+ elements_kind == UINT32_ELEMENTS) &&
+ !instr->CheckFlag(HInstruction::kUint32)) {
+ result = AssignEnvironment(result);
}
+ return result;
}
}
@@ -1885,13 +1892,10 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero);
- bool needs_environment = can_overflow || bailout_on_minus_zero;
HValue* least_const = instr->BetterLeftOperand();
HValue* most_const = instr->BetterRightOperand();
- LOperand* left;
-
// LMulConstI can handle a subset of constants:
// With support for overflow detection:
// -1, 0, 1, 2
@@ -1911,26 +1915,27 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
IsPowerOf2(constant_abs - 1))))) {
LConstantOperand* right = UseConstant(most_const);
bool need_register = IsPowerOf2(constant_abs) && !small_constant;
- left = need_register ? UseRegister(least_const)
- : UseRegisterAtStart(least_const);
- LMulConstIS* mul = new(zone()) LMulConstIS(left, right);
- if (needs_environment) AssignEnvironment(mul);
- return DefineAsRegister(mul);
+ LOperand* left = need_register ? UseRegister(least_const)
+ : UseRegisterAtStart(least_const);
+ LInstruction* result =
+ DefineAsRegister(new(zone()) LMulConstIS(left, right));
+ if ((bailout_on_minus_zero && constant <= 0) || can_overflow) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
}
- left = UseRegisterAtStart(least_const);
// LMulI/S can handle all cases, but it requires that a register is
// allocated for the second operand.
- LInstruction* result;
- if (instr->representation().IsSmi()) {
- LOperand* right = UseRegisterAtStart(most_const);
- result = DefineAsRegister(new(zone()) LMulS(left, right));
- } else {
- LOperand* right = UseRegisterAtStart(most_const);
- result = DefineAsRegister(new(zone()) LMulI(left, right));
+ LOperand* left = UseRegisterAtStart(least_const);
+ LOperand* right = UseRegisterAtStart(most_const);
+ LInstruction* result = instr->representation().IsSmi()
+ ? DefineAsRegister(new(zone()) LMulS(left, right))
+ : DefineAsRegister(new(zone()) LMulI(left, right));
+ if ((bailout_on_minus_zero && least_const != most_const) || can_overflow) {
+ result = AssignEnvironment(result);
}
- if (needs_environment) AssignEnvironment(result);
return result;
} else if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::MUL, instr);
@@ -1956,7 +1961,7 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
} else {
ASSERT(info()->IsStub());
CodeStubInterfaceDescriptor* descriptor =
- info()->code_stub()->GetInterfaceDescriptor(info()->isolate());
+ info()->code_stub()->GetInterfaceDescriptor();
int index = static_cast<int>(instr->index());
Register reg = descriptor->GetParameterRegister(index);
return DefineFixed(result, reg);
@@ -2045,6 +2050,117 @@ LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
}
+HBitwiseBinaryOperation* LChunkBuilder::CanTransformToShiftedOp(HValue* val,
+ HValue** left) {
+ if (!val->representation().IsInteger32()) return NULL;
+ if (!(val->IsBitwise() || val->IsAdd() || val->IsSub())) return NULL;
+
+ HBinaryOperation* hinstr = HBinaryOperation::cast(val);
+ HValue* hleft = hinstr->left();
+ HValue* hright = hinstr->right();
+ ASSERT(hleft->representation().Equals(hinstr->representation()));
+ ASSERT(hright->representation().Equals(hinstr->representation()));
+
+ if ((hright->IsConstant() &&
+ LikelyFitsImmField(hinstr, HConstant::cast(hright)->Integer32Value())) ||
+ (hinstr->IsCommutative() && hleft->IsConstant() &&
+ LikelyFitsImmField(hinstr, HConstant::cast(hleft)->Integer32Value()))) {
+ // The constant operand will likely fit in the immediate field. We are
+ // better off with
+ // lsl x8, x9, #imm
+ // add x0, x8, #imm2
+ // than with
+ // mov x16, #imm2
+ // add x0, x16, x9 LSL #imm
+ return NULL;
+ }
+
+ HBitwiseBinaryOperation* shift = NULL;
+ // TODO(aleram): We will miss situations where a shift operation is used by
+ // different instructions both as a left and right operands.
+ if (hright->IsBitwiseBinaryShift() &&
+ HBitwiseBinaryOperation::cast(hright)->right()->IsConstant()) {
+ shift = HBitwiseBinaryOperation::cast(hright);
+ if (left != NULL) {
+ *left = hleft;
+ }
+ } else if (hinstr->IsCommutative() &&
+ hleft->IsBitwiseBinaryShift() &&
+ HBitwiseBinaryOperation::cast(hleft)->right()->IsConstant()) {
+ shift = HBitwiseBinaryOperation::cast(hleft);
+ if (left != NULL) {
+ *left = hright;
+ }
+ } else {
+ return NULL;
+ }
+
+ if ((JSShiftAmountFromHConstant(shift->right()) == 0) && shift->IsShr()) {
+ // Shifts right by zero can deoptimize.
+ return NULL;
+ }
+
+ return shift;
+}
+
+
+bool LChunkBuilder::ShiftCanBeOptimizedAway(HBitwiseBinaryOperation* shift) {
+ if (!shift->representation().IsInteger32()) {
+ return false;
+ }
+ for (HUseIterator it(shift->uses()); !it.Done(); it.Advance()) {
+ if (shift != CanTransformToShiftedOp(it.value())) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+LInstruction* LChunkBuilder::TryDoOpWithShiftedRightOperand(
+ HBinaryOperation* instr) {
+ HValue* left;
+ HBitwiseBinaryOperation* shift = CanTransformToShiftedOp(instr, &left);
+
+ if ((shift != NULL) && ShiftCanBeOptimizedAway(shift)) {
+ return DoShiftedBinaryOp(instr, left, shift);
+ }
+ return NULL;
+}
+
+
+LInstruction* LChunkBuilder::DoShiftedBinaryOp(
+ HBinaryOperation* hinstr, HValue* hleft, HBitwiseBinaryOperation* hshift) {
+ ASSERT(hshift->IsBitwiseBinaryShift());
+ ASSERT(!hshift->IsShr() || (JSShiftAmountFromHConstant(hshift->right()) > 0));
+
+ LTemplateResultInstruction<1>* res;
+ LOperand* left = UseRegisterAtStart(hleft);
+ LOperand* right = UseRegisterAtStart(hshift->left());
+ LOperand* shift_amount = UseConstant(hshift->right());
+ Shift shift_op;
+ switch (hshift->opcode()) {
+ case HValue::kShl: shift_op = LSL; break;
+ case HValue::kShr: shift_op = LSR; break;
+ case HValue::kSar: shift_op = ASR; break;
+ default: UNREACHABLE(); shift_op = NO_SHIFT;
+ }
+
+ if (hinstr->IsBitwise()) {
+ res = new(zone()) LBitI(left, right, shift_op, shift_amount);
+ } else if (hinstr->IsAdd()) {
+ res = new(zone()) LAddI(left, right, shift_op, shift_amount);
+ } else {
+ ASSERT(hinstr->IsSub());
+ res = new(zone()) LSubI(left, right, shift_op, shift_amount);
+ }
+ if (hinstr->CheckFlag(HValue::kCanOverflow)) {
+ AssignEnvironment(res);
+ }
+ return DefineAsRegister(res);
+}
+
+
LInstruction* LChunkBuilder::DoShift(Token::Value op,
HBitwiseBinaryOperation* instr) {
if (instr->representation().IsTagged()) {
@@ -2056,6 +2172,10 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
+ if (ShiftCanBeOptimizedAway(instr)) {
+ return NULL;
+ }
+
LOperand* left = instr->representation().IsSmi()
? UseRegister(instr->left())
: UseRegisterAtStart(instr->left());
@@ -2066,8 +2186,7 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
int constant_value = 0;
if (right_value->IsConstant()) {
right = UseConstant(right_value);
- HConstant* constant = HConstant::cast(right_value);
- constant_value = constant->Integer32Value() & 0x1f;
+ constant_value = JSShiftAmountFromHConstant(right_value);
} else {
right = UseRegisterAtStart(right_value);
if (op == Token::ROR) {
@@ -2160,7 +2279,10 @@ LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
value = UseRegister(instr->value());
}
LInstruction* result = new(zone()) LStoreContextSlot(context, value, temp);
- return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
+ if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -2177,10 +2299,10 @@ LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
+ LOperand* key = UseRegisterOrConstant(instr->key());
LOperand* temp = NULL;
LOperand* elements = NULL;
LOperand* val = NULL;
- LOperand* key = UseRegisterOrConstantAtStart(instr->key());
if (!instr->is_typed_elements() &&
instr->value()->representation().IsTagged() &&
@@ -2294,7 +2416,7 @@ LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
LOperand* context = UseAny(instr->context());
LStringCharCodeAt* result =
new(zone()) LStringCharCodeAt(context, string, index);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ return AssignPointerMap(DefineAsRegister(result));
}
@@ -2324,6 +2446,12 @@ LInstruction* LChunkBuilder::DoSub(HSub* instr) {
if (instr->representation().IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
+
+ LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr);
+ if (shifted_operation != NULL) {
+ return shifted_operation;
+ }
+
LOperand *left;
if (instr->left()->IsConstant() &&
(HConstant::cast(instr->left())->Integer32Value() == 0)) {
@@ -2365,17 +2493,18 @@ LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) {
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- LOperand* object = UseRegister(instr->object());
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
+ LOperand* object = UseRegister(instr->object());
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, NULL,
TempRegister(), TempRegister());
return result;
} else {
+ LOperand* object = UseFixed(instr->object(), x0);
LOperand* context = UseFixed(instr->context(), cp);
LTransitionElementsKind* result =
- new(zone()) LTransitionElementsKind(object, context, TempRegister());
- return AssignPointerMap(result);
+ new(zone()) LTransitionElementsKind(object, context, NULL, NULL);
+ return MarkAsCall(result, instr);
}
}
@@ -2429,29 +2558,21 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister();
LOperand* temp3 = TempRegister();
- LMathAbsTagged* result =
- new(zone()) LMathAbsTagged(context, input, temp1, temp2, temp3);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ LInstruction* result = DefineAsRegister(
+ new(zone()) LMathAbsTagged(context, input, temp1, temp2, temp3));
+ return AssignEnvironment(AssignPointerMap(result));
} else {
LOperand* input = UseRegisterAtStart(instr->value());
- LMathAbs* result = new(zone()) LMathAbs(input);
- if (r.IsDouble()) {
- // The Double case can never fail so it doesn't need an environment.
- return DefineAsRegister(result);
- } else {
- ASSERT(r.IsInteger32() || r.IsSmi());
- // The Integer32 and Smi cases need an environment because they can
- // deoptimize on minimum representable number.
- return AssignEnvironment(DefineAsRegister(result));
- }
+ LInstruction* result = DefineAsRegister(new(zone()) LMathAbs(input));
+ if (!r.IsDouble()) result = AssignEnvironment(result);
+ return result;
}
}
case kMathExp: {
ASSERT(instr->representation().IsDouble());
ASSERT(instr->value()->representation().IsDouble());
LOperand* input = UseRegister(instr->value());
- // TODO(all): Implement TempFPRegister.
- LOperand* double_temp1 = FixedTemp(d24); // This was chosen arbitrarily.
+ LOperand* double_temp1 = TempDoubleRegister();
LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister();
LOperand* temp3 = TempRegister();
@@ -2460,14 +2581,16 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
return DefineAsRegister(result);
}
case kMathFloor: {
- ASSERT(instr->representation().IsInteger32());
ASSERT(instr->value()->representation().IsDouble());
- // TODO(jbramley): ARM64 can easily handle a double argument with frintm,
- // but we're never asked for it here. At the moment, we fall back to the
- // runtime if the result doesn't fit, like the other architectures.
LOperand* input = UseRegisterAtStart(instr->value());
- LMathFloor* result = new(zone()) LMathFloor(input);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ if (instr->representation().IsInteger32()) {
+ LMathFloorI* result = new(zone()) LMathFloorI(input);
+ return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ } else {
+ ASSERT(instr->representation().IsDouble());
+ LMathFloorD* result = new(zone()) LMathFloorD(input);
+ return DefineAsRegister(result);
+ }
}
case kMathLog: {
ASSERT(instr->representation().IsDouble());
@@ -2483,14 +2606,17 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
return DefineAsRegister(new(zone()) LMathPowHalf(input));
}
case kMathRound: {
- ASSERT(instr->representation().IsInteger32());
ASSERT(instr->value()->representation().IsDouble());
- // TODO(jbramley): As with kMathFloor, we can probably handle double
- // results fairly easily, but we are never asked for them.
LOperand* input = UseRegister(instr->value());
- LOperand* temp = FixedTemp(d24); // Choosen arbitrarily.
- LMathRound* result = new(zone()) LMathRound(input, temp);
- return AssignEnvironment(DefineAsRegister(result));
+ if (instr->representation().IsInteger32()) {
+ LOperand* temp = TempDoubleRegister();
+ LMathRoundI* result = new(zone()) LMathRoundI(input, temp);
+ return AssignEnvironment(DefineAsRegister(result));
+ } else {
+ ASSERT(instr->representation().IsDouble());
+ LMathRoundD* result = new(zone()) LMathRoundD(input);
+ return DefineAsRegister(result);
+ }
}
case kMathSqrt: {
ASSERT(instr->representation().IsDouble());
@@ -2561,7 +2687,9 @@ LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
LOperand* object = UseRegisterAtStart(instr->object());
LOperand* index = UseRegister(instr->index());
- return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index));
+ LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index);
+ LInstruction* result = DefineSameAsFirst(load);
+ return AssignPointerMap(result);
}
diff --git a/deps/v8/src/arm64/lithium-arm64.h b/deps/v8/src/arm64/lithium-arm64.h
index da3c5f17b5..3abc388fe1 100644
--- a/deps/v8/src/arm64/lithium-arm64.h
+++ b/deps/v8/src/arm64/lithium-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_LITHIUM_ARM64_H_
#define V8_ARM64_LITHIUM_ARM64_H_
@@ -138,11 +115,13 @@ class LCodeGen;
V(MathAbsTagged) \
V(MathClz32) \
V(MathExp) \
- V(MathFloor) \
+ V(MathFloorD) \
+ V(MathFloorI) \
V(MathLog) \
V(MathMinMax) \
V(MathPowHalf) \
- V(MathRound) \
+ V(MathRoundD) \
+ V(MathRoundI) \
V(MathSqrt) \
V(ModByConstI) \
V(ModByPowerOf2I) \
@@ -270,7 +249,9 @@ class LInstruction : public ZoneObject {
// Interface to the register allocator and iterators.
bool ClobbersTemps() const { return IsCall(); }
bool ClobbersRegisters() const { return IsCall(); }
- virtual bool ClobbersDoubleRegisters() const { return IsCall(); }
+ virtual bool ClobbersDoubleRegisters(Isolate* isolate) const {
+ return IsCall();
+ }
bool IsMarkedAsCall() const { return IsCall(); }
virtual bool HasResult() const = 0;
@@ -584,7 +565,14 @@ class LAddE V8_FINAL : public LTemplateInstruction<1, 2, 0> {
class LAddI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public:
- LAddI(LOperand* left, LOperand* right) {
+ LAddI(LOperand* left, LOperand* right)
+ : shift_(NO_SHIFT), shift_amount_(0) {
+ inputs_[0] = left;
+ inputs_[1] = right;
+ }
+
+ LAddI(LOperand* left, LOperand* right, Shift shift, LOperand* shift_amount)
+ : shift_(shift), shift_amount_(shift_amount) {
inputs_[0] = left;
inputs_[1] = right;
}
@@ -592,8 +580,15 @@ class LAddI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
LOperand* left() { return inputs_[0]; }
LOperand* right() { return inputs_[1]; }
+ Shift shift() const { return shift_; }
+ LOperand* shift_amount() const { return shift_amount_; }
+
DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
DECLARE_HYDROGEN_ACCESSOR(Add)
+
+ protected:
+ Shift shift_;
+ LOperand* shift_amount_;
};
@@ -753,7 +748,14 @@ class LBoundsCheck V8_FINAL : public LTemplateInstruction<0, 2, 0> {
class LBitI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public:
- LBitI(LOperand* left, LOperand* right) {
+ LBitI(LOperand* left, LOperand* right)
+ : shift_(NO_SHIFT), shift_amount_(0) {
+ inputs_[0] = left;
+ inputs_[1] = right;
+ }
+
+ LBitI(LOperand* left, LOperand* right, Shift shift, LOperand* shift_amount)
+ : shift_(shift), shift_amount_(shift_amount) {
inputs_[0] = left;
inputs_[1] = right;
}
@@ -761,10 +763,17 @@ class LBitI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
LOperand* left() { return inputs_[0]; }
LOperand* right() { return inputs_[1]; }
+ Shift shift() const { return shift_; }
+ LOperand* shift_amount() const { return shift_amount_; }
+
Token::Value op() const { return hydrogen()->op(); }
DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
DECLARE_HYDROGEN_ACCESSOR(Bitwise)
+
+ protected:
+ Shift shift_;
+ LOperand* shift_amount_;
};
@@ -887,7 +896,7 @@ class LCallRuntime V8_FINAL : public LTemplateInstruction<1, 1, 0> {
DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
- virtual bool ClobbersDoubleRegisters() const V8_OVERRIDE {
+ virtual bool ClobbersDoubleRegisters(Isolate* isolate) const V8_OVERRIDE {
return save_doubles() == kDontSaveFPRegs;
}
@@ -927,7 +936,7 @@ class LCheckInstanceType V8_FINAL : public LTemplateInstruction<0, 1, 1> {
class LCheckMaps V8_FINAL : public LTemplateInstruction<0, 1, 1> {
public:
- explicit LCheckMaps(LOperand* value, LOperand* temp = NULL) {
+ LCheckMaps(LOperand* value = NULL, LOperand* temp = NULL) {
inputs_[0] = value;
temps_[0] = temp;
}
@@ -1324,14 +1333,14 @@ class LDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 1> {
class LDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
public:
- LDivI(LOperand* left, LOperand* right, LOperand* temp) {
- inputs_[0] = left;
- inputs_[1] = right;
+ LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
+ inputs_[0] = dividend;
+ inputs_[1] = divisor;
temps_[0] = temp;
}
- LOperand* left() { return inputs_[0]; }
- LOperand* right() { return inputs_[1]; }
+ LOperand* dividend() { return inputs_[0]; }
+ LOperand* divisor() { return inputs_[1]; }
LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
@@ -1930,10 +1939,19 @@ class LMathExp V8_FINAL : public LUnaryMathOperation<4> {
};
-class LMathFloor V8_FINAL : public LUnaryMathOperation<0> {
+// Math.floor with a double result.
+class LMathFloorD V8_FINAL : public LUnaryMathOperation<0> {
+ public:
+ explicit LMathFloorD(LOperand* value) : LUnaryMathOperation<0>(value) { }
+ DECLARE_CONCRETE_INSTRUCTION(MathFloorD, "math-floor-d")
+};
+
+
+// Math.floor with an integer result.
+class LMathFloorI V8_FINAL : public LUnaryMathOperation<0> {
public:
- explicit LMathFloor(LOperand* value) : LUnaryMathOperation<0>(value) { }
- DECLARE_CONCRETE_INSTRUCTION(MathFloor, "math-floor")
+ explicit LMathFloorI(LOperand* value) : LUnaryMathOperation<0>(value) { }
+ DECLARE_CONCRETE_INSTRUCTION(MathFloorI, "math-floor-i")
};
@@ -2029,16 +2047,28 @@ class LMathPowHalf V8_FINAL : public LUnaryMathOperation<0> {
};
-class LMathRound V8_FINAL : public LUnaryMathOperation<1> {
+// Math.round with an integer result.
+class LMathRoundD V8_FINAL : public LUnaryMathOperation<0> {
+ public:
+ explicit LMathRoundD(LOperand* value)
+ : LUnaryMathOperation<0>(value) {
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(MathRoundD, "math-round-d")
+};
+
+
+// Math.round with an integer result.
+class LMathRoundI V8_FINAL : public LUnaryMathOperation<1> {
public:
- LMathRound(LOperand* value, LOperand* temp1)
+ LMathRoundI(LOperand* value, LOperand* temp1)
: LUnaryMathOperation<1>(value) {
temps_[0] = temp1;
}
LOperand* temp1() { return temps_[0]; }
- DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round")
+ DECLARE_CONCRETE_INSTRUCTION(MathRoundI, "math-round-i")
};
@@ -2384,6 +2414,10 @@ class LStoreKeyed : public LTemplateInstruction<0, 3, T> {
}
bool NeedsCanonicalization() {
+ if (hydrogen()->value()->IsAdd() || hydrogen()->value()->IsSub() ||
+ hydrogen()->value()->IsMul() || hydrogen()->value()->IsDiv()) {
+ return false;
+ }
return this->hydrogen()->NeedsCanonicalization();
}
uint32_t additional_index() const { return this->hydrogen()->index_offset(); }
@@ -2500,7 +2534,6 @@ class LStoreNamedField V8_FINAL : public LTemplateInstruction<0, 2, 2> {
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
- Handle<Map> transition() const { return hydrogen()->transition_map(); }
Representation representation() const {
return hydrogen()->field_representation();
}
@@ -2725,7 +2758,14 @@ class LStoreGlobalCell V8_FINAL : public LTemplateInstruction<0, 1, 2> {
class LSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public:
- LSubI(LOperand* left, LOperand* right) {
+ LSubI(LOperand* left, LOperand* right)
+ : shift_(NO_SHIFT), shift_amount_(0) {
+ inputs_[0] = left;
+ inputs_[1] = right;
+ }
+
+ LSubI(LOperand* left, LOperand* right, Shift shift, LOperand* shift_amount)
+ : shift_(shift), shift_amount_(shift_amount) {
inputs_[0] = left;
inputs_[1] = right;
}
@@ -2733,8 +2773,15 @@ class LSubI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
LOperand* left() { return inputs_[0]; }
LOperand* right() { return inputs_[1]; }
+ Shift shift() const { return shift_; }
+ LOperand* shift_amount() const { return shift_amount_; }
+
DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
DECLARE_HYDROGEN_ACCESSOR(Sub)
+
+ protected:
+ Shift shift_;
+ LOperand* shift_amount_;
};
@@ -2778,7 +2825,7 @@ class LTransitionElementsKind V8_FINAL : public LTemplateInstruction<0, 2, 2> {
LTransitionElementsKind(LOperand* object,
LOperand* context,
LOperand* temp1,
- LOperand* temp2 = NULL) {
+ LOperand* temp2) {
inputs_[0] = object;
inputs_[1] = context;
temps_[0] = temp1;
@@ -3042,6 +3089,9 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
// Temporary operand that must be in a register.
MUST_USE_RESULT LUnallocated* TempRegister();
+ // Temporary operand that must be in a double register.
+ MUST_USE_RESULT LUnallocated* TempDoubleRegister();
+
// Temporary operand that must be in a fixed double register.
MUST_USE_RESULT LOperand* FixedTemp(DoubleRegister reg);
@@ -3075,6 +3125,39 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
void VisitInstruction(HInstruction* current);
void DoBasicBlock(HBasicBlock* block);
+ int JSShiftAmountFromHConstant(HValue* constant) {
+ return HConstant::cast(constant)->Integer32Value() & 0x1f;
+ }
+ bool LikelyFitsImmField(HInstruction* instr, int imm) {
+ if (instr->IsAdd() || instr->IsSub()) {
+ return Assembler::IsImmAddSub(imm) || Assembler::IsImmAddSub(-imm);
+ } else {
+ ASSERT(instr->IsBitwise());
+ unsigned unused_n, unused_imm_s, unused_imm_r;
+ return Assembler::IsImmLogical(imm, kWRegSizeInBits,
+ &unused_n, &unused_imm_s, &unused_imm_r);
+ }
+ }
+
+ // Indicates if a sequence of the form
+ // lsl x8, x9, #imm
+ // add x0, x1, x8
+ // can be replaced with:
+ // add x0, x1, x9 LSL #imm
+ // If this is not possible, the function returns NULL. Otherwise it returns a
+ // pointer to the shift instruction that would be optimized away.
+ HBitwiseBinaryOperation* CanTransformToShiftedOp(HValue* val,
+ HValue** left = NULL);
+ // Checks if all uses of the shift operation can optimize it away.
+ bool ShiftCanBeOptimizedAway(HBitwiseBinaryOperation* shift);
+ // Attempts to merge the binary operation and an eventual previous shift
+ // operation into a single operation. Returns the merged instruction on
+ // success, and NULL otherwise.
+ LInstruction* TryDoOpWithShiftedRightOperand(HBinaryOperation* op);
+ LInstruction* DoShiftedBinaryOp(HBinaryOperation* instr,
+ HValue* left,
+ HBitwiseBinaryOperation* shift);
+
LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
LInstruction* DoArithmeticD(Token::Value op,
HArithmeticBinaryOperation* instr);
diff --git a/deps/v8/src/arm64/lithium-codegen-arm64.cc b/deps/v8/src/arm64/lithium-codegen-arm64.cc
index cd931e934c..b064d3da9f 100644
--- a/deps/v8/src/arm64/lithium-codegen-arm64.cc
+++ b/deps/v8/src/arm64/lithium-codegen-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -376,6 +353,7 @@ int LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) {
void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment,
Safepoint::DeoptMode mode) {
+ environment->set_has_been_used();
if (!environment->HasBeenRegistered()) {
int frame_count = 0;
int jsframe_count = 0;
@@ -429,8 +407,9 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
ASSERT(ToRegister(instr->result()).Is(x0));
int arity = instr->arity();
- CallFunctionStub stub(arity, instr->hydrogen()->function_flags());
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+ after_push_argument_ = false;
}
@@ -443,8 +422,9 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
// No cell in x2 for construct type feedback in optimized code.
__ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
- CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
+ after_push_argument_ = false;
ASSERT(ToRegister(instr->result()).is(x0));
}
@@ -465,8 +445,8 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
: DONT_OVERRIDE;
if (instr->arity() == 0) {
- ArrayNoArgumentConstructorStub stub(kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
} else if (instr->arity() == 1) {
Label done;
if (IsFastPackedElementsKind(kind)) {
@@ -477,19 +457,22 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
__ Cbz(x10, &packed_case);
ElementsKind holey_kind = GetHoleyElementsKind(kind);
- ArraySingleArgumentConstructorStub stub(holey_kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArraySingleArgumentConstructorStub stub(isolate(),
+ holey_kind,
+ override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
__ B(&done);
__ Bind(&packed_case);
}
- ArraySingleArgumentConstructorStub stub(kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
__ Bind(&done);
} else {
- ArrayNArgumentsConstructorStub stub(kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
}
+ after_push_argument_ = false;
ASSERT(ToRegister(instr->result()).is(x0));
}
@@ -511,7 +494,7 @@ void LCodeGen::LoadContextFromDeferred(LOperand* context) {
if (context->IsRegister()) {
__ Mov(cp, ToRegister(context));
} else if (context->IsStackSlot()) {
- __ Ldr(cp, ToMemOperand(context));
+ __ Ldr(cp, ToMemOperand(context, kMustUseFramePointer));
} else if (context->IsConstantOperand()) {
HConstant* constant =
chunk_->LookupConstant(LConstantOperand::cast(context));
@@ -709,7 +692,7 @@ bool LCodeGen::GeneratePrologue() {
Comment(";;; Allocate local context");
// Argument to NewContext is the function, which is in x1.
if (heap_slots <= FastNewContextStub::kMaximumSlots) {
- FastNewContextStub stub(heap_slots);
+ FastNewContextStub stub(isolate(), heap_slots);
__ CallStub(&stub);
} else {
__ Push(x1);
@@ -909,13 +892,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
PopulateDeoptimizationData(code);
- info()->CommitDependencies(code);
-}
-
-
-void LCodeGen::Abort(BailoutReason reason) {
- info()->set_bailout_reason(reason);
- status_ = ABORTED;
}
@@ -924,7 +900,7 @@ void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
if (length == 0) return;
Handle<DeoptimizationInputData> data =
- factory()->NewDeoptimizationInputData(length, TENURED);
+ DeoptimizationInputData::New(isolate(), length, TENURED);
Handle<ByteArray> translations =
translations_.CreateByteArray(isolate()->factory());
@@ -1232,9 +1208,9 @@ Operand LCodeGen::ToOperand32(LOperand* op, IntegerSignedness signedness) {
Representation r = chunk_->LookupLiteralRepresentation(const_op);
if (r.IsInteger32()) {
ASSERT(constant->HasInteger32Value());
- return Operand(signedness == SIGNED_INT32
- ? constant->Integer32Value()
- : static_cast<uint32_t>(constant->Integer32Value()));
+ return (signedness == SIGNED_INT32)
+ ? Operand(constant->Integer32Value())
+ : Operand(static_cast<uint32_t>(constant->Integer32Value()));
} else {
// Other constants not implemented.
Abort(kToOperand32UnsupportedImmediate);
@@ -1252,13 +1228,38 @@ static ptrdiff_t ArgumentsOffsetWithoutFrame(ptrdiff_t index) {
}
-MemOperand LCodeGen::ToMemOperand(LOperand* op) const {
+MemOperand LCodeGen::ToMemOperand(LOperand* op, StackMode stack_mode) const {
ASSERT(op != NULL);
ASSERT(!op->IsRegister());
ASSERT(!op->IsDoubleRegister());
ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot());
if (NeedsEagerFrame()) {
- return MemOperand(fp, StackSlotOffset(op->index()));
+ int fp_offset = StackSlotOffset(op->index());
+ if (op->index() >= 0) {
+ // Loads and stores have a bigger reach in positive offset than negative.
+ // When the load or the store can't be done in one instruction via fp
+ // (too big negative offset), we try to access via jssp (positive offset).
+ // We can reference a stack slot from jssp only if jssp references the end
+ // of the stack slots. It's not the case when:
+ // - stack_mode != kCanUseStackPointer: this is the case when a deferred
+ // code saved the registers.
+ // - after_push_argument_: arguments has been pushed for a call.
+ // - inlined_arguments_: inlined arguments have been pushed once. All the
+ // remainder of the function cannot trust jssp any longer.
+ // - saves_caller_doubles: some double registers have been pushed, jssp
+ // references the end of the double registers and not the end of the
+ // stack slots.
+ // Also, if the offset from fp is small enough to make a load/store in
+ // one instruction, we use a fp access.
+ if ((stack_mode == kCanUseStackPointer) && !after_push_argument_ &&
+ !inlined_arguments_ && !is_int9(fp_offset) &&
+ !info()->saves_caller_doubles()) {
+ int jssp_offset =
+ (GetStackSlotCount() - op->index() - 1) * kPointerSize;
+ return MemOperand(masm()->StackPointer(), jssp_offset);
+ }
+ }
+ return MemOperand(fp, fp_offset);
} else {
// Retrieve parameter without eager stack-frame relative to the
// stack-pointer.
@@ -1275,6 +1276,21 @@ Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
}
+template<class LI>
+Operand LCodeGen::ToShiftedRightOperand32(LOperand* right, LI* shift_info,
+ IntegerSignedness signedness) {
+ if (shift_info->shift() == NO_SHIFT) {
+ return (signedness == SIGNED_INT32) ? ToOperand32I(right)
+ : ToOperand32U(right);
+ } else {
+ return Operand(
+ ToRegister32(right),
+ shift_info->shift(),
+ JSShiftAmountFromLConstant(shift_info->shift_amount()));
+ }
+}
+
+
bool LCodeGen::IsSmi(LConstantOperand* op) const {
return chunk_->LookupLiteralRepresentation(op).IsSmi();
}
@@ -1471,7 +1487,8 @@ void LCodeGen::DoAddI(LAddI* instr) {
bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
Register result = ToRegister32(instr->result());
Register left = ToRegister32(instr->left());
- Operand right = ToOperand32I(instr->right());
+ Operand right = ToShiftedRightOperand32I(instr->right(), instr);
+
if (can_overflow) {
__ Adds(result, left, right);
DeoptimizeIf(vs, instr->environment());
@@ -1648,6 +1665,10 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
+ // We push some arguments and they will be pop in an other block. We can't
+ // trust that jssp references the end of the stack slots until the end of
+ // the function.
+ inlined_arguments_ = true;
Register result = ToRegister(instr->result());
if (instr->hydrogen()->from_inlined()) {
@@ -1737,15 +1758,15 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
ASSERT(ToRegister(instr->right()).is(x0));
ASSERT(ToRegister(instr->result()).is(x0));
- BinaryOpICStub stub(instr->op(), NO_OVERWRITE);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
void LCodeGen::DoBitI(LBitI* instr) {
Register result = ToRegister32(instr->result());
Register left = ToRegister32(instr->left());
- Operand right = ToOperand32U(instr->right());
+ Operand right = ToShiftedRightOperand32U(instr->right(), instr);
switch (instr->op()) {
case Token::BIT_AND: __ And(result, left, right); break;
@@ -1774,36 +1795,25 @@ void LCodeGen::DoBitS(LBitS* instr) {
}
-void LCodeGen::ApplyCheckIf(Condition cc, LBoundsCheck* check) {
- if (FLAG_debug_code && check->hydrogen()->skip_check()) {
- __ Assert(InvertCondition(cc), kEliminatedBoundsCheckFailed);
- } else {
- DeoptimizeIf(cc, check->environment());
- }
-}
-
-
void LCodeGen::DoBoundsCheck(LBoundsCheck *instr) {
- if (instr->hydrogen()->skip_check()) return;
-
+ Condition cond = instr->hydrogen()->allow_equality() ? hi : hs;
+ ASSERT(instr->hydrogen()->index()->representation().IsInteger32());
ASSERT(instr->hydrogen()->length()->representation().IsInteger32());
- Register length = ToRegister32(instr->length());
-
if (instr->index()->IsConstantOperand()) {
- int constant_index =
- ToInteger32(LConstantOperand::cast(instr->index()));
-
- if (instr->hydrogen()->length()->representation().IsSmi()) {
- __ Cmp(length, Smi::FromInt(constant_index));
- } else {
- __ Cmp(length, constant_index);
- }
+ Operand index = ToOperand32I(instr->index());
+ Register length = ToRegister32(instr->length());
+ __ Cmp(length, index);
+ cond = ReverseConditionForCmp(cond);
} else {
- ASSERT(instr->hydrogen()->index()->representation().IsInteger32());
- __ Cmp(length, ToRegister32(instr->index()));
+ Register index = ToRegister32(instr->index());
+ Operand length = ToOperand32I(instr->length());
+ __ Cmp(index, length);
+ }
+ if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
+ __ Assert(InvertCondition(cond), kEliminatedBoundsCheckFailed);
+ } else {
+ DeoptimizeIf(cond, instr->environment());
}
- Condition condition = instr->hydrogen()->allow_equality() ? lo : ls;
- ApplyCheckIf(condition, instr);
}
@@ -2027,6 +2037,7 @@ void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
__ Call(target);
}
generator.AfterCall();
+ after_push_argument_ = false;
}
@@ -2046,11 +2057,13 @@ void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
__ Call(x10);
RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
+ after_push_argument_ = false;
}
void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
CallRuntime(instr->function(), instr->arity(), instr);
+ after_push_argument_ = false;
}
@@ -2059,23 +2072,24 @@ void LCodeGen::DoCallStub(LCallStub* instr) {
ASSERT(ToRegister(instr->result()).is(x0));
switch (instr->hydrogen()->major_key()) {
case CodeStub::RegExpExec: {
- RegExpExecStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ RegExpExecStub stub(isolate());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
case CodeStub::SubString: {
- SubStringStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ SubStringStub stub(isolate());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
case CodeStub::StringCompare: {
- StringCompareStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ StringCompareStub stub(isolate());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
default:
UNREACHABLE();
}
+ after_push_argument_ = false;
}
@@ -2117,9 +2131,11 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
Register object_;
};
- if (instr->hydrogen()->CanOmitMapChecks()) {
- ASSERT(instr->value() == NULL);
- ASSERT(instr->temp() == NULL);
+ if (instr->hydrogen()->IsStabilityCheck()) {
+ const UniqueSet<Map>* maps = instr->hydrogen()->maps();
+ for (int i = 0; i < maps->size(); ++i) {
+ AddStabilityDependency(maps->at(i).handle());
+ }
return;
}
@@ -2129,24 +2145,26 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
__ Ldr(map_reg, FieldMemOperand(object, HeapObject::kMapOffset));
DeferredCheckMaps* deferred = NULL;
- if (instr->hydrogen()->has_migration_target()) {
+ if (instr->hydrogen()->HasMigrationTarget()) {
deferred = new(zone()) DeferredCheckMaps(this, instr, object);
__ Bind(deferred->check_maps());
}
- UniqueSet<Map> map_set = instr->hydrogen()->map_set();
+ const UniqueSet<Map>* maps = instr->hydrogen()->maps();
Label success;
- for (int i = 0; i < map_set.size(); i++) {
- Handle<Map> map = map_set.at(i).handle();
+ for (int i = 0; i < maps->size() - 1; i++) {
+ Handle<Map> map = maps->at(i).handle();
__ CompareMap(map_reg, map);
__ B(eq, &success);
}
+ Handle<Map> map = maps->at(maps->size() - 1).handle();
+ __ CompareMap(map_reg, map);
// We didn't match a map.
- if (instr->hydrogen()->has_migration_target()) {
- __ B(deferred->entry());
+ if (instr->hydrogen()->HasMigrationTarget()) {
+ __ B(ne, deferred->entry());
} else {
- Deoptimize(instr->environment());
+ DeoptimizeIf(ne, instr->environment());
}
__ Bind(&success);
@@ -2529,9 +2547,16 @@ void LCodeGen::DoConstantS(LConstantS* instr) {
void LCodeGen::DoConstantT(LConstantT* instr) {
- Handle<Object> value = instr->value(isolate());
+ Handle<Object> object = instr->value(isolate());
AllowDeferredHandleDereference smi_check;
- __ LoadObject(ToRegister(instr->result()), value);
+ if (instr->hydrogen()->HasObjectMap()) {
+ Handle<Map> object_map = instr->hydrogen()->ObjectMap().handle();
+ ASSERT(object->IsHeapObject());
+ ASSERT(!object_map->is_stable() ||
+ *object_map == Handle<HeapObject>::cast(object)->map());
+ USE(object_map);
+ }
+ __ LoadObject(ToRegister(instr->result()), object);
}
@@ -2580,19 +2605,15 @@ void LCodeGen::DoDateField(LDateField* instr) {
Register temp1 = x10;
Register temp2 = x11;
Smi* index = instr->index();
- Label runtime, done, deopt, obj_ok;
+ Label runtime, done;
ASSERT(object.is(result) && object.Is(x0));
ASSERT(instr->IsMarkedAsCall());
- __ JumpIfSmi(object, &deopt);
+ DeoptimizeIfSmi(object, instr->environment());
__ CompareObjectType(object, temp1, temp1, JS_DATE_TYPE);
- __ B(eq, &obj_ok);
-
- __ Bind(&deopt);
- Deoptimize(instr->environment());
+ DeoptimizeIf(ne, instr->environment());
- __ Bind(&obj_ok);
if (index->value() == 0) {
__ Ldr(result, FieldMemOperand(object, JSDate::kValueOffset));
} else {
@@ -2636,7 +2657,7 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
Register dividend = ToRegister32(instr->dividend());
int32_t divisor = instr->divisor();
Register result = ToRegister32(instr->result());
- ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor))));
+ ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor)));
ASSERT(!result.is(dividend));
// Check for (0 / -x) that will produce negative zero.
@@ -2707,10 +2728,11 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
}
+// TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI.
void LCodeGen::DoDivI(LDivI* instr) {
HBinaryOperation* hdiv = instr->hydrogen();
- Register dividend = ToRegister32(instr->left());
- Register divisor = ToRegister32(instr->right());
+ Register dividend = ToRegister32(instr->dividend());
+ Register divisor = ToRegister32(instr->divisor());
Register result = ToRegister32(instr->result());
// Issue the division first, and then check for any deopt cases whilst the
@@ -2722,10 +2744,9 @@ void LCodeGen::DoDivI(LDivI* instr) {
return;
}
- Label deopt;
// Check for x / 0.
if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
- __ Cbz(divisor, &deopt);
+ DeoptimizeIfZero(divisor, instr->environment());
}
// Check for (0 / -x) as that will produce negative zero.
@@ -2737,7 +2758,7 @@ void LCodeGen::DoDivI(LDivI* instr) {
// If the divisor >= 0 (pl, the opposite of mi) set the flags to
// condition ne, so we don't deopt, ie. positive divisor doesn't deopt.
__ Ccmp(dividend, 0, NoFlag, mi);
- __ B(eq, &deopt);
+ DeoptimizeIf(eq, instr->environment());
}
// Check for (kMinInt / -1).
@@ -2749,19 +2770,13 @@ void LCodeGen::DoDivI(LDivI* instr) {
// -1. If overflow is clear, set the flags for condition ne, as the
// dividend isn't -1, and thus we shouldn't deopt.
__ Ccmp(divisor, -1, NoFlag, vs);
- __ B(eq, &deopt);
+ DeoptimizeIf(eq, instr->environment());
}
// Compute remainder and deopt if it's not zero.
Register remainder = ToRegister32(instr->temp());
__ Msub(remainder, result, divisor, dividend);
- __ Cbnz(remainder, &deopt);
-
- Label div_ok;
- __ B(&div_ok);
- __ Bind(&deopt);
- Deoptimize(instr->environment());
- __ Bind(&div_ok);
+ DeoptimizeIfNotZero(remainder, instr->environment());
}
@@ -2773,7 +2788,7 @@ void LCodeGen::DoDoubleToIntOrSmi(LDoubleToIntOrSmi* instr) {
DeoptimizeIfMinusZero(input, instr->environment());
}
- __ TryConvertDoubleToInt32(result, input, double_scratch());
+ __ TryRepresentDoubleAsInt32(result, input, double_scratch());
DeoptimizeIf(ne, instr->environment());
if (instr->tag_result()) {
@@ -2806,10 +2821,11 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
// space for nested functions that don't need literals cloning.
bool pretenure = instr->hydrogen()->pretenure();
if (!pretenure && instr->hydrogen()->has_no_literals()) {
- FastNewClosureStub stub(instr->hydrogen()->strict_mode(),
+ FastNewClosureStub stub(isolate(),
+ instr->hydrogen()->strict_mode(),
instr->hydrogen()->is_generator());
__ Mov(x2, Operand(instr->hydrogen()->shared_info()));
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
} else {
__ Mov(x2, Operand(instr->hydrogen()->shared_info()));
__ Mov(x1, Operand(pretenure ? factory()->true_value()
@@ -2848,19 +2864,18 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
ASSERT(instr->IsMarkedAsCall());
ASSERT(object.Is(x0));
- Label deopt;
-
- __ JumpIfRoot(object, Heap::kUndefinedValueRootIndex, &deopt);
+ DeoptimizeIfRoot(object, Heap::kUndefinedValueRootIndex,
+ instr->environment());
__ LoadRoot(null_value, Heap::kNullValueRootIndex);
__ Cmp(object, null_value);
- __ B(eq, &deopt);
+ DeoptimizeIf(eq, instr->environment());
- __ JumpIfSmi(object, &deopt);
+ DeoptimizeIfSmi(object, instr->environment());
STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
__ CompareObjectType(object, x1, x1, LAST_JS_PROXY_TYPE);
- __ B(le, &deopt);
+ DeoptimizeIf(le, instr->environment());
Label use_cache, call_runtime;
__ CheckEnumCache(object, null_value, x1, x2, x3, x4, &call_runtime);
@@ -2868,16 +2883,13 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
__ Ldr(object, FieldMemOperand(object, HeapObject::kMapOffset));
__ B(&use_cache);
- __ Bind(&deopt);
- Deoptimize(instr->environment());
-
// Get the set of properties to enumerate.
__ Bind(&call_runtime);
__ Push(object);
CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
__ Ldr(x1, FieldMemOperand(object, HeapObject::kMapOffset));
- __ JumpIfNotRoot(x1, Heap::kMetaMapRootIndex, &deopt);
+ DeoptimizeIfNotRoot(x1, Heap::kMetaMapRootIndex, instr->environment());
__ Bind(&use_cache);
}
@@ -2985,8 +2997,8 @@ void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
ASSERT(ToRegister(instr->left()).Is(InstanceofStub::left()));
ASSERT(ToRegister(instr->right()).Is(InstanceofStub::right()));
- InstanceofStub stub(InstanceofStub::kArgsInRegisters);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
// InstanceofStub returns a result in x0:
// 0 => not an instance
@@ -3100,8 +3112,8 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
ASSERT(ToRegister(instr->value()).Is(InstanceofStub::left()));
__ LoadObject(InstanceofStub::right(), instr->function());
- InstanceofStub stub(flags);
- CallCodeGeneric(stub.GetCode(isolate()),
+ InstanceofStub stub(isolate(), flags);
+ CallCodeGeneric(stub.GetCode(),
RelocInfo::CODE_TARGET,
instr,
RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
@@ -3144,6 +3156,7 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
instr,
x1);
}
+ after_push_argument_ = false;
}
@@ -3285,11 +3298,11 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
Register function = ToRegister(instr->function());
Register result = ToRegister(instr->result());
Register temp = ToRegister(instr->temp());
- Label deopt;
// Check that the function really is a function. Leaves map in the result
// register.
- __ JumpIfNotObjectType(function, result, temp, JS_FUNCTION_TYPE, &deopt);
+ __ CompareObjectType(function, result, temp, JS_FUNCTION_TYPE);
+ DeoptimizeIf(ne, instr->environment());
// Make sure that the function has an instance prototype.
Label non_instance;
@@ -3301,7 +3314,8 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
JSFunction::kPrototypeOrInitialMapOffset));
// Check that the function has a prototype or an initial map.
- __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &deopt);
+ DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex,
+ instr->environment());
// If the function does not have an initial map, we're done.
Label done;
@@ -3316,11 +3330,6 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
// map.
__ Bind(&non_instance);
__ Ldr(result, FieldMemOperand(result, Map::kConstructorOffset));
- __ B(&done);
-
- // Deoptimize case.
- __ Bind(&deopt);
- Deoptimize(instr->environment());
// All done.
__ Bind(&done);
@@ -3359,51 +3368,28 @@ MemOperand LCodeGen::PrepareKeyedExternalArrayOperand(
ElementsKind elements_kind,
int additional_index) {
int element_size_shift = ElementsKindToShiftSize(elements_kind);
- int additional_offset = IsFixedTypedArrayElementsKind(elements_kind)
- ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
- : 0;
+ int additional_offset = additional_index << element_size_shift;
+ if (IsFixedTypedArrayElementsKind(elements_kind)) {
+ additional_offset += FixedTypedArrayBase::kDataOffset - kHeapObjectTag;
+ }
if (key_is_constant) {
- int base_offset = ((constant_key + additional_index) << element_size_shift);
- return MemOperand(base, base_offset + additional_offset);
+ int key_offset = constant_key << element_size_shift;
+ return MemOperand(base, key_offset + additional_offset);
}
- if (additional_index == 0) {
- if (key_is_smi) {
- // Key is smi: untag, and scale by element size.
- __ Add(scratch, base, Operand::UntagSmiAndScale(key, element_size_shift));
- return MemOperand(scratch, additional_offset);
- } else {
- // Key is not smi, and element size is not byte: scale by element size.
- if (additional_offset == 0) {
- return MemOperand(base, key, SXTW, element_size_shift);
- } else {
- __ Add(scratch, base, Operand(key, SXTW, element_size_shift));
- return MemOperand(scratch, additional_offset);
- }
- }
- } else {
- // TODO(all): Try to combine these cases a bit more intelligently.
- if (additional_offset == 0) {
- if (key_is_smi) {
- __ SmiUntag(scratch, key);
- __ Add(scratch.W(), scratch.W(), additional_index);
- } else {
- __ Add(scratch.W(), key.W(), additional_index);
- }
- return MemOperand(base, scratch, LSL, element_size_shift);
- } else {
- if (key_is_smi) {
- __ Add(scratch, base,
- Operand::UntagSmiAndScale(key, element_size_shift));
- } else {
- __ Add(scratch, base, Operand(key, SXTW, element_size_shift));
- }
- return MemOperand(
- scratch,
- (additional_index << element_size_shift) + additional_offset);
- }
+ if (key_is_smi) {
+ __ Add(scratch, base, Operand::UntagSmiAndScale(key, element_size_shift));
+ return MemOperand(scratch, additional_offset);
+ }
+
+ if (additional_offset == 0) {
+ return MemOperand(base, key, SXTW, element_size_shift);
}
+
+ ASSERT(!AreAliased(scratch, key));
+ __ Add(scratch, base, additional_offset);
+ return MemOperand(scratch, key, SXTW, element_size_shift);
}
@@ -3496,11 +3482,14 @@ void LCodeGen::DoLoadKeyedExternal(LLoadKeyedExternal* instr) {
}
-void LCodeGen::CalcKeyedArrayBaseRegister(Register base,
- Register elements,
- Register key,
- bool key_is_tagged,
- ElementsKind elements_kind) {
+MemOperand LCodeGen::PrepareKeyedArrayOperand(Register base,
+ Register elements,
+ Register key,
+ bool key_is_tagged,
+ ElementsKind elements_kind,
+ Representation representation,
+ int additional_index) {
+ STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) && (kSmiTag == 0));
int element_size_shift = ElementsKindToShiftSize(elements_kind);
// Even though the HLoad/StoreKeyed instructions force the input
@@ -3509,11 +3498,28 @@ void LCodeGen::CalcKeyedArrayBaseRegister(Register base,
// can be tagged, so that case must be handled here, too.
if (key_is_tagged) {
__ Add(base, elements, Operand::UntagSmiAndScale(key, element_size_shift));
+ if (representation.IsInteger32()) {
+ ASSERT(elements_kind == FAST_SMI_ELEMENTS);
+ // Read or write only the most-significant 32 bits in the case of fast smi
+ // arrays.
+ return UntagSmiFieldMemOperand(base, additional_index);
+ } else {
+ return FieldMemOperand(base, additional_index);
+ }
} else {
// Sign extend key because it could be a 32-bit negative value or contain
// garbage in the top 32-bits. The address computation happens in 64-bit.
ASSERT((element_size_shift >= 0) && (element_size_shift <= 4));
- __ Add(base, elements, Operand(key, SXTW, element_size_shift));
+ if (representation.IsInteger32()) {
+ ASSERT(elements_kind == FAST_SMI_ELEMENTS);
+ // Read or write only the most-significant 32 bits in the case of fast smi
+ // arrays.
+ __ Add(base, elements, Operand(key, SXTW, element_size_shift));
+ return UntagSmiFieldMemOperand(base, additional_index);
+ } else {
+ __ Add(base, elements, additional_index - kHeapObjectTag);
+ return MemOperand(base, key, SXTW, element_size_shift);
+ }
}
}
@@ -3521,8 +3527,7 @@ void LCodeGen::CalcKeyedArrayBaseRegister(Register base,
void LCodeGen::DoLoadKeyedFixedDouble(LLoadKeyedFixedDouble* instr) {
Register elements = ToRegister(instr->elements());
DoubleRegister result = ToDoubleRegister(instr->result());
- Register load_base;
- int offset = 0;
+ MemOperand mem_op;
if (instr->key()->IsConstantOperand()) {
ASSERT(instr->hydrogen()->RequiresHoleCheck() ||
@@ -3532,27 +3537,30 @@ void LCodeGen::DoLoadKeyedFixedDouble(LLoadKeyedFixedDouble* instr) {
if (constant_key & 0xf0000000) {
Abort(kArrayIndexConstantValueTooBig);
}
- offset = FixedDoubleArray::OffsetOfElementAt(constant_key +
- instr->additional_index());
- load_base = elements;
+ int offset = FixedDoubleArray::OffsetOfElementAt(constant_key +
+ instr->additional_index());
+ mem_op = FieldMemOperand(elements, offset);
} else {
- load_base = ToRegister(instr->temp());
+ Register load_base = ToRegister(instr->temp());
Register key = ToRegister(instr->key());
bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi();
- CalcKeyedArrayBaseRegister(load_base, elements, key, key_is_tagged,
- instr->hydrogen()->elements_kind());
- offset = FixedDoubleArray::OffsetOfElementAt(instr->additional_index());
+ int offset = FixedDoubleArray::OffsetOfElementAt(instr->additional_index());
+ mem_op = PrepareKeyedArrayOperand(load_base, elements, key, key_is_tagged,
+ instr->hydrogen()->elements_kind(),
+ instr->hydrogen()->representation(),
+ offset);
}
- __ Ldr(result, FieldMemOperand(load_base, offset));
+
+ __ Ldr(result, mem_op);
if (instr->hydrogen()->RequiresHoleCheck()) {
Register scratch = ToRegister(instr->temp());
-
- // TODO(all): Is it faster to reload this value to an integer register, or
- // move from fp to integer?
- __ Fmov(scratch, result);
- __ Cmp(scratch, kHoleNanInt64);
- DeoptimizeIf(eq, instr->environment());
+ // Detect the hole NaN by adding one to the integer representation of the
+ // result, and checking for overflow.
+ STATIC_ASSERT(kHoleNanInt64 == 0x7fffffffffffffff);
+ __ Ldr(scratch, mem_op);
+ __ Cmn(scratch, 1);
+ DeoptimizeIf(vs, instr->environment());
}
}
@@ -3560,35 +3568,35 @@ void LCodeGen::DoLoadKeyedFixedDouble(LLoadKeyedFixedDouble* instr) {
void LCodeGen::DoLoadKeyedFixed(LLoadKeyedFixed* instr) {
Register elements = ToRegister(instr->elements());
Register result = ToRegister(instr->result());
- Register load_base;
- int offset = 0;
+ MemOperand mem_op;
+ Representation representation = instr->hydrogen()->representation();
if (instr->key()->IsConstantOperand()) {
ASSERT(instr->temp() == NULL);
LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
- offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
- instr->additional_index());
- load_base = elements;
+ int offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
+ instr->additional_index());
+ if (representation.IsInteger32()) {
+ ASSERT(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS);
+ STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) &&
+ (kSmiTag == 0));
+ mem_op = UntagSmiFieldMemOperand(elements, offset);
+ } else {
+ mem_op = FieldMemOperand(elements, offset);
+ }
} else {
- load_base = ToRegister(instr->temp());
+ Register load_base = ToRegister(instr->temp());
Register key = ToRegister(instr->key());
bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi();
- CalcKeyedArrayBaseRegister(load_base, elements, key, key_is_tagged,
- instr->hydrogen()->elements_kind());
- offset = FixedArray::OffsetOfElementAt(instr->additional_index());
- }
- Representation representation = instr->hydrogen()->representation();
+ int offset = FixedArray::OffsetOfElementAt(instr->additional_index());
- if (representation.IsInteger32() &&
- instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS) {
- STATIC_ASSERT(kSmiValueSize == 32 && kSmiShift == 32 && kSmiTag == 0);
- __ Load(result, UntagSmiFieldMemOperand(load_base, offset),
- Representation::Integer32());
- } else {
- __ Load(result, FieldMemOperand(load_base, offset),
- representation);
+ mem_op = PrepareKeyedArrayOperand(load_base, elements, key, key_is_tagged,
+ instr->hydrogen()->elements_kind(),
+ representation, offset);
}
+ __ Load(result, mem_op, representation);
+
if (instr->hydrogen()->RequiresHoleCheck()) {
if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
DeoptimizeIfNotSmi(result, instr->environment());
@@ -3688,10 +3696,8 @@ void LCodeGen::DoMathAbs(LMathAbs* instr) {
: ToRegister32(instr->value());
Register result = r.IsSmi() ? ToRegister(instr->result())
: ToRegister32(instr->result());
- Label done;
- __ Abs(result, input, NULL, &done);
- Deoptimize(instr->environment());
- __ Bind(&done);
+ __ Abs(result, input);
+ DeoptimizeIf(vs, instr->environment());
}
}
@@ -3832,9 +3838,15 @@ void LCodeGen::DoMathExp(LMathExp* instr) {
}
-void LCodeGen::DoMathFloor(LMathFloor* instr) {
- // TODO(jbramley): If we could provide a double result, we could use frintm
- // and produce a valid double result in a single instruction.
+void LCodeGen::DoMathFloorD(LMathFloorD* instr) {
+ DoubleRegister input = ToDoubleRegister(instr->value());
+ DoubleRegister result = ToDoubleRegister(instr->result());
+
+ __ Frintm(result, input);
+}
+
+
+void LCodeGen::DoMathFloorI(LMathFloorI* instr) {
DoubleRegister input = ToDoubleRegister(instr->value());
Register result = ToRegister(instr->result());
@@ -3868,22 +3880,28 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
}
// If the divisor is negative, we have to negate and handle edge cases.
- Label not_kmin_int, done;
__ Negs(result, dividend);
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
DeoptimizeIf(eq, instr->environment());
}
- if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
- // Note that we could emit branch-free code, but that would need one more
- // register.
- if (divisor == -1) {
- DeoptimizeIf(vs, instr->environment());
- } else {
- __ B(vc, &not_kmin_int);
- __ Mov(result, kMinInt / divisor);
- __ B(&done);
- }
+
+ // If the negation could not overflow, simply shifting is OK.
+ if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
+ __ Mov(result, Operand(dividend, ASR, shift));
+ return;
+ }
+
+ // Dividing by -1 is basically negation, unless we overflow.
+ if (divisor == -1) {
+ DeoptimizeIf(vs, instr->environment());
+ return;
}
+
+ // Using a conditional data processing instruction would need 1 more register.
+ Label not_kmin_int, done;
+ __ B(vc, &not_kmin_int);
+ __ Mov(result, kMinInt / divisor);
+ __ B(&done);
__ bind(&not_kmin_int);
__ Mov(result, Operand(dividend, ASR, shift));
__ bind(&done);
@@ -3936,6 +3954,7 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
}
+// TODO(svenpanne) Refactor this to avoid code duplication with DoDivI.
void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
Register dividend = ToRegister32(instr->dividend());
Register divisor = ToRegister32(instr->divisor());
@@ -4034,7 +4053,7 @@ void LCodeGen::DoPower(LPower* instr) {
ASSERT(ToDoubleRegister(instr->result()).is(d0));
if (exponent_type.IsSmi()) {
- MathPowStub stub(MathPowStub::TAGGED);
+ MathPowStub stub(isolate(), MathPowStub::TAGGED);
__ CallStub(&stub);
} else if (exponent_type.IsTagged()) {
Label no_deopt;
@@ -4043,25 +4062,54 @@ void LCodeGen::DoPower(LPower* instr) {
DeoptimizeIfNotRoot(x0, Heap::kHeapNumberMapRootIndex,
instr->environment());
__ Bind(&no_deopt);
- MathPowStub stub(MathPowStub::TAGGED);
+ MathPowStub stub(isolate(), MathPowStub::TAGGED);
__ CallStub(&stub);
} else if (exponent_type.IsInteger32()) {
// Ensure integer exponent has no garbage in top 32-bits, as MathPowStub
// supports large integer exponents.
Register exponent = ToRegister(instr->right());
__ Sxtw(exponent, exponent);
- MathPowStub stub(MathPowStub::INTEGER);
+ MathPowStub stub(isolate(), MathPowStub::INTEGER);
__ CallStub(&stub);
} else {
ASSERT(exponent_type.IsDouble());
- MathPowStub stub(MathPowStub::DOUBLE);
+ MathPowStub stub(isolate(), MathPowStub::DOUBLE);
__ CallStub(&stub);
}
}
-void LCodeGen::DoMathRound(LMathRound* instr) {
- // TODO(jbramley): We could provide a double result here using frint.
+void LCodeGen::DoMathRoundD(LMathRoundD* instr) {
+ DoubleRegister input = ToDoubleRegister(instr->value());
+ DoubleRegister result = ToDoubleRegister(instr->result());
+ DoubleRegister scratch_d = double_scratch();
+
+ ASSERT(!AreAliased(input, result, scratch_d));
+
+ Label done;
+
+ __ Frinta(result, input);
+ __ Fcmp(input, 0.0);
+ __ Fccmp(result, input, ZFlag, lt);
+ // The result is correct if the input was in [-0, +infinity], or was a
+ // negative integral value.
+ __ B(eq, &done);
+
+ // Here the input is negative, non integral, with an exponent lower than 52.
+ // We do not have to worry about the 0.49999999999999994 (0x3fdfffffffffffff)
+ // case. So we can safely add 0.5.
+ __ Fmov(scratch_d, 0.5);
+ __ Fadd(result, input, scratch_d);
+ __ Frintm(result, result);
+ // The range [-0.5, -0.0[ yielded +0.0. Force the sign to negative.
+ __ Fabs(result, result);
+ __ Fneg(result, result);
+
+ __ Bind(&done);
+}
+
+
+void LCodeGen::DoMathRoundI(LMathRoundI* instr) {
DoubleRegister input = ToDoubleRegister(instr->value());
DoubleRegister temp1 = ToDoubleRegister(instr->temp1());
Register result = ToRegister(instr->result());
@@ -4100,7 +4148,7 @@ void LCodeGen::DoMathRound(LMathRound* instr) {
// Since we're providing a 32-bit result, we can implement ties-to-infinity by
// adding 0.5 to the input, then taking the floor of the result. This does not
// work for very large positive doubles because adding 0.5 would cause an
- // intermediate rounding stage, so a different approach will be necessary if a
+ // intermediate rounding stage, so a different approach is necessary when a
// double result is needed.
__ Fadd(temp1, input, dot_five);
__ Fcvtms(result, temp1);
@@ -4221,25 +4269,16 @@ void LCodeGen::DoModI(LModI* instr) {
Register divisor = ToRegister32(instr->right());
Register result = ToRegister32(instr->result());
- Label deopt, done;
+ Label done;
// modulo = dividend - quotient * divisor
__ Sdiv(result, dividend, divisor);
if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
- // Combine the deoptimization sites.
- Label ok;
- __ Cbnz(divisor, &ok);
- __ Bind(&deopt);
- Deoptimize(instr->environment());
- __ Bind(&ok);
+ DeoptimizeIfZero(divisor, instr->environment());
}
__ Msub(result, result, divisor, dividend);
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
__ Cbnz(result, &done);
- if (deopt.is_bound()) { // TODO(all) This is a hack, remove this...
- __ Tbnz(dividend, kWSignBit, &deopt);
- } else {
- DeoptimizeIfNegative(dividend, instr->environment());
- }
+ DeoptimizeIfNegative(dividend, instr->environment());
}
__ Bind(&done);
}
@@ -4648,6 +4687,7 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) {
Abort(kDoPushArgumentNotImplementedForDoubleType);
} else {
__ Push(ToRegister(argument));
+ after_push_argument_ = true;
}
}
@@ -4703,13 +4743,13 @@ MemOperand LCodeGen::BuildSeqStringOperand(Register string,
return FieldMemOperand(string, SeqString::kHeaderSize + offset);
}
+ __ Add(temp, string, SeqString::kHeaderSize - kHeapObjectTag);
if (encoding == String::ONE_BYTE_ENCODING) {
- __ Add(temp, string, Operand(ToRegister32(index), SXTW));
+ return MemOperand(temp, ToRegister32(index), SXTW);
} else {
STATIC_ASSERT(kUC16Size == 2);
- __ Add(temp, string, Operand(ToRegister32(index), SXTW, 1));
+ return MemOperand(temp, ToRegister32(index), SXTW, 1);
}
- return FieldMemOperand(temp, SeqString::kHeaderSize);
}
@@ -4826,7 +4866,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
}
} else {
ASSERT(right_op->IsConstantOperand());
- int shift_count = ToInteger32(LConstantOperand::cast(right_op)) & 0x1f;
+ int shift_count = JSShiftAmountFromLConstant(right_op);
if (shift_count == 0) {
if ((instr->op() == Token::SHR) && instr->can_deopt()) {
DeoptimizeIfNegative(left, instr->environment());
@@ -4889,7 +4929,7 @@ void LCodeGen::DoShiftS(LShiftS* instr) {
}
} else {
ASSERT(right_op->IsConstantOperand());
- int shift_count = ToInteger32(LConstantOperand::cast(right_op)) & 0x1f;
+ int shift_count = JSShiftAmountFromLConstant(right_op);
if (shift_count == 0) {
if ((instr->op() == Token::SHR) && instr->can_deopt()) {
DeoptimizeIfNegative(left, instr->environment());
@@ -5152,34 +5192,32 @@ void LCodeGen::DoStoreKeyedExternal(LStoreKeyedExternal* instr) {
void LCodeGen::DoStoreKeyedFixedDouble(LStoreKeyedFixedDouble* instr) {
Register elements = ToRegister(instr->elements());
DoubleRegister value = ToDoubleRegister(instr->value());
- Register store_base = no_reg;
- int offset = 0;
+ MemOperand mem_op;
if (instr->key()->IsConstantOperand()) {
int constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
if (constant_key & 0xf0000000) {
Abort(kArrayIndexConstantValueTooBig);
}
- offset = FixedDoubleArray::OffsetOfElementAt(constant_key +
- instr->additional_index());
- store_base = elements;
+ int offset = FixedDoubleArray::OffsetOfElementAt(constant_key +
+ instr->additional_index());
+ mem_op = FieldMemOperand(elements, offset);
} else {
- store_base = ToRegister(instr->temp());
+ Register store_base = ToRegister(instr->temp());
Register key = ToRegister(instr->key());
bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi();
- CalcKeyedArrayBaseRegister(store_base, elements, key, key_is_tagged,
- instr->hydrogen()->elements_kind());
- offset = FixedDoubleArray::OffsetOfElementAt(instr->additional_index());
+ int offset = FixedDoubleArray::OffsetOfElementAt(instr->additional_index());
+ mem_op = PrepareKeyedArrayOperand(store_base, elements, key, key_is_tagged,
+ instr->hydrogen()->elements_kind(),
+ instr->hydrogen()->representation(),
+ offset);
}
if (instr->NeedsCanonicalization()) {
- DoubleRegister dbl_scratch = double_scratch();
- __ Fmov(dbl_scratch,
- FixedDoubleArray::canonical_not_the_hole_nan_as_double());
- __ Fmaxnm(dbl_scratch, dbl_scratch, value);
- __ Str(dbl_scratch, FieldMemOperand(store_base, offset));
+ __ CanonicalizeNaN(double_scratch(), value);
+ __ Str(double_scratch(), mem_op);
} else {
- __ Str(value, FieldMemOperand(store_base, offset));
+ __ Str(value, mem_op);
}
}
@@ -5190,37 +5228,41 @@ void LCodeGen::DoStoreKeyedFixed(LStoreKeyedFixed* instr) {
Register scratch = no_reg;
Register store_base = no_reg;
Register key = no_reg;
- int offset = 0;
+ MemOperand mem_op;
if (!instr->key()->IsConstantOperand() ||
instr->hydrogen()->NeedsWriteBarrier()) {
scratch = ToRegister(instr->temp());
}
+ Representation representation = instr->hydrogen()->value()->representation();
if (instr->key()->IsConstantOperand()) {
LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
- offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
- instr->additional_index());
+ int offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
+ instr->additional_index());
store_base = elements;
+ if (representation.IsInteger32()) {
+ ASSERT(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY);
+ ASSERT(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS);
+ STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) &&
+ (kSmiTag == 0));
+ mem_op = UntagSmiFieldMemOperand(store_base, offset);
+ } else {
+ mem_op = FieldMemOperand(store_base, offset);
+ }
} else {
store_base = scratch;
key = ToRegister(instr->key());
bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi();
- CalcKeyedArrayBaseRegister(store_base, elements, key, key_is_tagged,
- instr->hydrogen()->elements_kind());
- offset = FixedArray::OffsetOfElementAt(instr->additional_index());
- }
- Representation representation = instr->hydrogen()->value()->representation();
- if (representation.IsInteger32()) {
- ASSERT(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY);
- ASSERT(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS);
- STATIC_ASSERT(kSmiValueSize == 32 && kSmiShift == 32 && kSmiTag == 0);
- __ Store(value, UntagSmiFieldMemOperand(store_base, offset),
- Representation::Integer32());
- } else {
- __ Store(value, FieldMemOperand(store_base, offset), representation);
+ int offset = FixedArray::OffsetOfElementAt(instr->additional_index());
+
+ mem_op = PrepareKeyedArrayOperand(store_base, elements, key, key_is_tagged,
+ instr->hydrogen()->elements_kind(),
+ representation, offset);
}
+ __ Store(value, mem_op, representation);
+
if (instr->hydrogen()->NeedsWriteBarrier()) {
ASSERT(representation.IsTagged());
// This assignment may cause element_addr to alias store_base.
@@ -5229,7 +5271,7 @@ void LCodeGen::DoStoreKeyedFixed(LStoreKeyedFixed* instr) {
instr->hydrogen()->value()->IsHeapObject()
? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
// Compute address of modified element and store it into key register.
- __ Add(element_addr, store_base, offset - kHeapObjectTag);
+ __ Add(element_addr, mem_op.base(), mem_op.OffsetAsOperand());
__ RecordWrite(elements, element_addr, value, GetLinkRegisterState(),
kSaveFPRegs, EMIT_REMEMBERED_SET, check_needed);
}
@@ -5254,18 +5296,17 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
Register object = ToRegister(instr->object());
HObjectAccess access = instr->hydrogen()->access();
- Handle<Map> transition = instr->transition();
int offset = access.offset();
if (access.IsExternalMemory()) {
- ASSERT(transition.is_null());
+ ASSERT(!instr->hydrogen()->has_transition());
ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
Register value = ToRegister(instr->value());
__ Store(value, MemOperand(object, offset), representation);
return;
} else if (representation.IsDouble()) {
- ASSERT(transition.is_null());
ASSERT(access.IsInobject());
+ ASSERT(!instr->hydrogen()->has_transition());
ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
FPRegister value = ToDoubleRegister(instr->value());
__ Str(value, FieldMemOperand(object, offset));
@@ -5284,11 +5325,13 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
!instr->hydrogen()->value()->type().IsHeapObject()) {
DeoptimizeIfSmi(value, instr->environment());
- // We know that value is a smi now, so we can omit the check below.
+ // We know now that value is not a smi, so we can omit the check below.
check_needed = OMIT_SMI_CHECK;
}
- if (!transition.is_null()) {
+ if (instr->hydrogen()->has_transition()) {
+ Handle<Map> transition = instr->hydrogen()->transition_map();
+ AddDeprecationDependency(transition);
// Store the new map value.
Register new_map_value = ToRegister(instr->temp0());
__ Mov(new_map_value, Operand(transition));
@@ -5365,9 +5408,10 @@ void LCodeGen::DoStringAdd(LStringAdd* instr) {
ASSERT(ToRegister(instr->context()).is(cp));
ASSERT(ToRegister(instr->left()).Is(x1));
ASSERT(ToRegister(instr->right()).Is(x0));
- StringAddStub stub(instr->hydrogen()->flags(),
+ StringAddStub stub(isolate(),
+ instr->hydrogen()->flags(),
instr->hydrogen()->pretenure_flag());
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
@@ -5440,8 +5484,8 @@ void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
__ Cmp(char_code, String::kMaxOneByteCharCode);
__ B(hi, deferred->entry());
__ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex);
- __ Add(result, result, Operand(char_code, SXTW, kPointerSizeLog2));
- __ Ldr(result, FieldMemOperand(result, FixedArray::kHeaderSize));
+ __ Add(result, result, FixedArray::kHeaderSize - kHeapObjectTag);
+ __ Ldr(result, MemOperand(result, char_code, SXTW, kPointerSizeLog2));
__ CompareRoot(result, Heap::kUndefinedValueRootIndex);
__ B(eq, deferred->entry());
__ Bind(deferred->exit());
@@ -5483,7 +5527,8 @@ void LCodeGen::DoSubI(LSubI* instr) {
bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
Register result = ToRegister32(instr->result());
Register left = ToRegister32(instr->left());
- Operand right = ToOperand32I(instr->right());
+ Operand right = ToShiftedRightOperand32I(instr->right(), instr);
+
if (can_overflow) {
__ Subs(result, left, right);
DeoptimizeIf(vs, instr->environment());
@@ -5557,7 +5602,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr,
// A heap number: load value and convert to int32 using non-truncating
// function. If the result is out of range, branch to deoptimize.
__ Ldr(dbl_scratch1, FieldMemOperand(input, HeapNumber::kValueOffset));
- __ TryConvertDoubleToInt32(output, dbl_scratch1, dbl_scratch2);
+ __ TryRepresentDoubleAsInt32(output, dbl_scratch1, dbl_scratch2);
DeoptimizeIf(ne, instr->environment());
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
@@ -5659,7 +5704,6 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
Register object = ToRegister(instr->object());
- Register temp1 = ToRegister(instr->temp1());
Handle<Map> from_map = instr->original_map();
Handle<Map> to_map = instr->transitioned_map();
@@ -5667,26 +5711,34 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
ElementsKind to_kind = instr->to_kind();
Label not_applicable;
- __ CheckMap(object, temp1, from_map, &not_applicable, DONT_DO_SMI_CHECK);
if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
+ Register temp1 = ToRegister(instr->temp1());
Register new_map = ToRegister(instr->temp2());
+ __ CheckMap(object, temp1, from_map, &not_applicable, DONT_DO_SMI_CHECK);
__ Mov(new_map, Operand(to_map));
__ Str(new_map, FieldMemOperand(object, HeapObject::kMapOffset));
// Write barrier.
__ RecordWriteField(object, HeapObject::kMapOffset, new_map, temp1,
GetLinkRegisterState(), kDontSaveFPRegs);
} else {
+ {
+ UseScratchRegisterScope temps(masm());
+ // Use the temp register only in a restricted scope - the codegen checks
+ // that we do not use any register across a call.
+ __ CheckMap(object, temps.AcquireX(), from_map, &not_applicable,
+ DONT_DO_SMI_CHECK);
+ }
+ ASSERT(object.is(x0));
ASSERT(ToRegister(instr->context()).is(cp));
PushSafepointRegistersScope scope(
this, Safepoint::kWithRegistersAndDoubles);
- __ Mov(x0, object);
__ Mov(x1, Operand(to_map));
bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
- TransitionElementsKindStub stub(from_kind, to_kind, is_js_array);
+ TransitionElementsKindStub stub(isolate(), from_kind, to_kind, is_js_array);
__ CallStub(&stub);
RecordSafepointWithRegistersAndDoubles(
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
+ instr->pointer_map(), 0, Safepoint::kLazyDeopt);
}
__ Bind(&not_applicable);
}
@@ -5698,8 +5750,8 @@ void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
Register temp2 = ToRegister(instr->temp2());
Label no_memento_found;
- __ JumpIfJSArrayHasAllocationMemento(object, temp1, temp2, &no_memento_found);
- Deoptimize(instr->environment());
+ __ TestJSArrayForAllocationMemento(object, temp1, temp2, &no_memento_found);
+ DeoptimizeIf(eq, instr->environment());
__ Bind(&no_memento_found);
}
@@ -5727,7 +5779,8 @@ void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
Label* false_label = instr->FalseLabel(chunk_);
Register value = ToRegister(instr->value());
- if (type_name->Equals(heap()->number_string())) {
+ Factory* factory = isolate()->factory();
+ if (String::Equals(type_name, factory->number_string())) {
ASSERT(instr->temp1() != NULL);
Register map = ToRegister(instr->temp1());
@@ -5736,7 +5789,7 @@ void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
__ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
EmitBranch(instr, eq);
- } else if (type_name->Equals(heap()->string_string())) {
+ } else if (String::Equals(type_name, factory->string_string())) {
ASSERT((instr->temp1() != NULL) && (instr->temp2() != NULL));
Register map = ToRegister(instr->temp1());
Register scratch = ToRegister(instr->temp2());
@@ -5747,7 +5800,7 @@ void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
__ Ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset));
EmitTestAndBranch(instr, eq, scratch, 1 << Map::kIsUndetectable);
- } else if (type_name->Equals(heap()->symbol_string())) {
+ } else if (String::Equals(type_name, factory->symbol_string())) {
ASSERT((instr->temp1() != NULL) && (instr->temp2() != NULL));
Register map = ToRegister(instr->temp1());
Register scratch = ToRegister(instr->temp2());
@@ -5756,16 +5809,17 @@ void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
__ CompareObjectType(value, map, scratch, SYMBOL_TYPE);
EmitBranch(instr, eq);
- } else if (type_name->Equals(heap()->boolean_string())) {
+ } else if (String::Equals(type_name, factory->boolean_string())) {
__ JumpIfRoot(value, Heap::kTrueValueRootIndex, true_label);
__ CompareRoot(value, Heap::kFalseValueRootIndex);
EmitBranch(instr, eq);
- } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) {
+ } else if (FLAG_harmony_typeof &&
+ String::Equals(type_name, factory->null_string())) {
__ CompareRoot(value, Heap::kNullValueRootIndex);
EmitBranch(instr, eq);
- } else if (type_name->Equals(heap()->undefined_string())) {
+ } else if (String::Equals(type_name, factory->undefined_string())) {
ASSERT(instr->temp1() != NULL);
Register scratch = ToRegister(instr->temp1());
@@ -5776,7 +5830,7 @@ void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
__ Ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
EmitTestAndBranch(instr, ne, scratch, 1 << Map::kIsUndetectable);
- } else if (type_name->Equals(heap()->function_string())) {
+ } else if (String::Equals(type_name, factory->function_string())) {
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
ASSERT(instr->temp1() != NULL);
Register type = ToRegister(instr->temp1());
@@ -5786,7 +5840,7 @@ void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
// HeapObject's type has been loaded into type register by JumpIfObjectType.
EmitCompareAndBranch(instr, eq, type, JS_FUNCTION_PROXY_TYPE);
- } else if (type_name->Equals(heap()->object_string())) {
+ } else if (String::Equals(type_name, factory->object_string())) {
ASSERT((instr->temp1() != NULL) && (instr->temp2() != NULL));
Register map = ToRegister(instr->temp1());
Register scratch = ToRegister(instr->temp2());
@@ -5832,7 +5886,7 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
// If the receiver is null or undefined, we have to pass the global object as
// a receiver to normal functions. Values have to be passed unchanged to
// builtins and strict-mode functions.
- Label global_object, done, deopt;
+ Label global_object, done, copy_receiver;
if (!instr->hydrogen()->known_function()) {
__ Ldr(result, FieldMemOperand(function,
@@ -5843,10 +5897,10 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
FieldMemOperand(result, SharedFunctionInfo::kCompilerHintsOffset));
// Do not transform the receiver to object for strict mode functions.
- __ Tbnz(result, SharedFunctionInfo::kStrictModeFunction, &done);
+ __ Tbnz(result, SharedFunctionInfo::kStrictModeFunction, &copy_receiver);
// Do not transform the receiver to object for builtins.
- __ Tbnz(result, SharedFunctionInfo::kNative, &done);
+ __ Tbnz(result, SharedFunctionInfo::kNative, &copy_receiver);
}
// Normal function. Replace undefined or null with global receiver.
@@ -5854,32 +5908,78 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
__ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, &global_object);
// Deoptimize if the receiver is not a JS object.
- __ JumpIfSmi(receiver, &deopt);
+ DeoptimizeIfSmi(receiver, instr->environment());
__ CompareObjectType(receiver, result, result, FIRST_SPEC_OBJECT_TYPE);
- __ Mov(result, receiver);
- __ B(ge, &done);
- // Otherwise, fall through to deopt.
-
- __ Bind(&deopt);
+ __ B(ge, &copy_receiver);
Deoptimize(instr->environment());
__ Bind(&global_object);
__ Ldr(result, FieldMemOperand(function, JSFunction::kContextOffset));
__ Ldr(result, ContextMemOperand(result, Context::GLOBAL_OBJECT_INDEX));
__ Ldr(result, FieldMemOperand(result, GlobalObject::kGlobalReceiverOffset));
+ __ B(&done);
+ __ Bind(&copy_receiver);
+ __ Mov(result, receiver);
__ Bind(&done);
}
+void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
+ Register result,
+ Register object,
+ Register index) {
+ PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
+ __ Push(object);
+ __ Push(index);
+ __ Mov(cp, 0);
+ __ CallRuntimeSaveDoubles(Runtime::kLoadMutableDouble);
+ RecordSafepointWithRegisters(
+ instr->pointer_map(), 2, Safepoint::kNoLazyDeopt);
+ __ StoreToSafepointRegisterSlot(x0, result);
+}
+
+
void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
+ class DeferredLoadMutableDouble V8_FINAL : public LDeferredCode {
+ public:
+ DeferredLoadMutableDouble(LCodeGen* codegen,
+ LLoadFieldByIndex* instr,
+ Register result,
+ Register object,
+ Register index)
+ : LDeferredCode(codegen),
+ instr_(instr),
+ result_(result),
+ object_(object),
+ index_(index) {
+ }
+ virtual void Generate() V8_OVERRIDE {
+ codegen()->DoDeferredLoadMutableDouble(instr_, result_, object_, index_);
+ }
+ virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
+ private:
+ LLoadFieldByIndex* instr_;
+ Register result_;
+ Register object_;
+ Register index_;
+ };
Register object = ToRegister(instr->object());
Register index = ToRegister(instr->index());
Register result = ToRegister(instr->result());
__ AssertSmi(index);
+ DeferredLoadMutableDouble* deferred;
+ deferred = new(zone()) DeferredLoadMutableDouble(
+ this, instr, result, object, index);
+
Label out_of_object, done;
+
+ __ TestAndBranchIfAnySet(
+ index, reinterpret_cast<uint64_t>(Smi::FromInt(1)), deferred->entry());
+ __ Mov(index, Operand(index, ASR, 1));
+
__ Cmp(index, Smi::FromInt(0));
__ B(lt, &out_of_object);
@@ -5895,6 +5995,7 @@ void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
__ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2));
__ Ldr(result, FieldMemOperand(result,
FixedArray::kHeaderSize - kPointerSize));
+ __ Bind(deferred->exit());
__ Bind(&done);
}
diff --git a/deps/v8/src/arm64/lithium-codegen-arm64.h b/deps/v8/src/arm64/lithium-codegen-arm64.h
index b1d8b70d5b..8c25e63405 100644
--- a/deps/v8/src/arm64/lithium-codegen-arm64.h
+++ b/deps/v8/src/arm64/lithium-codegen-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_LITHIUM_CODEGEN_ARM64_H_
#define V8_ARM64_LITHIUM_CODEGEN_ARM64_H_
@@ -35,7 +12,7 @@
#include "lithium-codegen.h"
#include "safepoint-table.h"
#include "scopes.h"
-#include "v8utils.h"
+#include "utils.h"
namespace v8 {
namespace internal {
@@ -60,10 +37,16 @@ class LCodeGen: public LCodeGenBase {
frame_is_built_(false),
safepoints_(info->zone()),
resolver_(this),
- expected_safepoint_kind_(Safepoint::kSimple) {
+ expected_safepoint_kind_(Safepoint::kSimple),
+ after_push_argument_(false),
+ inlined_arguments_(false) {
PopulateDeoptimizationLiteralsWithInlinedFunctions();
}
+ ~LCodeGen() {
+ ASSERT(!after_push_argument_ || inlined_arguments_);
+ }
+
// Simple accessors.
Scope* scope() const { return scope_; }
@@ -98,6 +81,7 @@ class LCodeGen: public LCodeGenBase {
// information on it.
void FinishCode(Handle<Code> code);
+ enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
// Support for converting LOperands to assembler types.
// LOperand must be a register.
Register ToRegister(LOperand* op) const;
@@ -105,9 +89,30 @@ class LCodeGen: public LCodeGenBase {
Operand ToOperand(LOperand* op);
Operand ToOperand32I(LOperand* op);
Operand ToOperand32U(LOperand* op);
- MemOperand ToMemOperand(LOperand* op) const;
+ enum StackMode { kMustUseFramePointer, kCanUseStackPointer };
+ MemOperand ToMemOperand(LOperand* op,
+ StackMode stack_mode = kCanUseStackPointer) const;
Handle<Object> ToHandle(LConstantOperand* op) const;
+ template<class LI>
+ Operand ToShiftedRightOperand32I(LOperand* right,
+ LI* shift_info) {
+ return ToShiftedRightOperand32(right, shift_info, SIGNED_INT32);
+ }
+ template<class LI>
+ Operand ToShiftedRightOperand32U(LOperand* right,
+ LI* shift_info) {
+ return ToShiftedRightOperand32(right, shift_info, UNSIGNED_INT32);
+ }
+ template<class LI>
+ Operand ToShiftedRightOperand32(LOperand* right,
+ LI* shift_info,
+ IntegerSignedness signedness);
+
+ int JSShiftAmountFromLConstant(LOperand* constant) {
+ return ToInteger32(LConstantOperand::cast(constant)) & 0x1f;
+ }
+
// TODO(jbramley): Examine these helpers and check that they make sense.
// IsInteger32Constant returns true for smi constants, for example.
bool IsInteger32Constant(LConstantOperand* op) const;
@@ -137,7 +142,6 @@ class LCodeGen: public LCodeGenBase {
Label* exit,
Label* allocation_entry);
- enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
void DoDeferredNumberTagU(LInstruction* instr,
LOperand* value,
LOperand* temp1,
@@ -149,6 +153,10 @@ class LCodeGen: public LCodeGenBase {
void DoDeferredAllocate(LAllocate* instr);
void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr);
void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
+ void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
+ Register result,
+ Register object,
+ Register index);
Operand ToOperand32(LOperand* op, IntegerSignedness signedness);
@@ -224,7 +232,7 @@ class LCodeGen: public LCodeGenBase {
Deoptimizer::BailoutType* override_bailout_type = NULL);
void Deoptimize(LEnvironment* environment,
Deoptimizer::BailoutType* override_bailout_type = NULL);
- void DeoptimizeIf(Condition cc, LEnvironment* environment);
+ void DeoptimizeIf(Condition cond, LEnvironment* environment);
void DeoptimizeIfZero(Register rt, LEnvironment* environment);
void DeoptimizeIfNotZero(Register rt, LEnvironment* environment);
void DeoptimizeIfNegative(Register rt, LEnvironment* environment);
@@ -239,7 +247,6 @@ class LCodeGen: public LCodeGenBase {
void DeoptimizeIfMinusZero(DoubleRegister input, LEnvironment* environment);
void DeoptimizeIfBitSet(Register rt, int bit, LEnvironment* environment);
void DeoptimizeIfBitClear(Register rt, int bit, LEnvironment* environment);
- void ApplyCheckIf(Condition cc, LBoundsCheck* check);
MemOperand PrepareKeyedExternalArrayOperand(Register key,
Register base,
@@ -249,19 +256,19 @@ class LCodeGen: public LCodeGenBase {
int constant_key,
ElementsKind elements_kind,
int additional_index);
- void CalcKeyedArrayBaseRegister(Register base,
- Register elements,
- Register key,
- bool key_is_tagged,
- ElementsKind elements_kind);
+ MemOperand PrepareKeyedArrayOperand(Register base,
+ Register elements,
+ Register key,
+ bool key_is_tagged,
+ ElementsKind elements_kind,
+ Representation representation,
+ int additional_index);
void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
Safepoint::DeoptMode mode);
int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
- void Abort(BailoutReason reason);
-
void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
// Emit frame translation commands for an environment.
@@ -368,6 +375,15 @@ class LCodeGen: public LCodeGenBase {
Safepoint::Kind expected_safepoint_kind_;
+ // This flag is true when we are after a push (but before a call).
+ // In this situation, jssp no longer references the end of the stack slots so,
+ // we can only reference a stack slot via fp.
+ bool after_push_argument_;
+ // If we have inlined arguments, we are no longer able to use jssp because
+ // jssp is modified and we never know if we are in a block after or before
+ // the pop of the arguments (which restores jssp).
+ bool inlined_arguments_;
+
int old_position_;
class PushSafepointRegistersScope BASE_EMBEDDED {
@@ -387,12 +403,12 @@ class LCodeGen: public LCodeGenBase {
codegen_->masm_->Mov(to_be_pushed_lr, lr);
switch (codegen_->expected_safepoint_kind_) {
case Safepoint::kWithRegisters: {
- StoreRegistersStateStub stub(kDontSaveFPRegs);
+ StoreRegistersStateStub stub(codegen_->isolate(), kDontSaveFPRegs);
codegen_->masm_->CallStub(&stub);
break;
}
case Safepoint::kWithRegistersAndDoubles: {
- StoreRegistersStateStub stub(kSaveFPRegs);
+ StoreRegistersStateStub stub(codegen_->isolate(), kSaveFPRegs);
codegen_->masm_->CallStub(&stub);
break;
}
@@ -406,12 +422,12 @@ class LCodeGen: public LCodeGenBase {
ASSERT((kind & Safepoint::kWithRegisters) != 0);
switch (kind) {
case Safepoint::kWithRegisters: {
- RestoreRegistersStateStub stub(kDontSaveFPRegs);
+ RestoreRegistersStateStub stub(codegen_->isolate(), kDontSaveFPRegs);
codegen_->masm_->CallStub(&stub);
break;
}
case Safepoint::kWithRegistersAndDoubles: {
- RestoreRegistersStateStub stub(kSaveFPRegs);
+ RestoreRegistersStateStub stub(codegen_->isolate(), kSaveFPRegs);
codegen_->masm_->CallStub(&stub);
break;
}
diff --git a/deps/v8/src/arm64/lithium-gap-resolver-arm64.cc b/deps/v8/src/arm64/lithium-gap-resolver-arm64.cc
index f0a2e6bd0e..c721cb48a8 100644
--- a/deps/v8/src/arm64/lithium-gap-resolver-arm64.cc
+++ b/deps/v8/src/arm64/lithium-gap-resolver-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/arm64/lithium-gap-resolver-arm64.h b/deps/v8/src/arm64/lithium-gap-resolver-arm64.h
index d1637b65a9..ae67190734 100644
--- a/deps/v8/src/arm64/lithium-gap-resolver-arm64.h
+++ b/deps/v8/src/arm64/lithium-gap-resolver-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_LITHIUM_GAP_RESOLVER_ARM64_H_
#define V8_ARM64_LITHIUM_GAP_RESOLVER_ARM64_H_
diff --git a/deps/v8/src/arm64/macro-assembler-arm64-inl.h b/deps/v8/src/arm64/macro-assembler-arm64-inl.h
index d660d36016..7c9258a9ca 100644
--- a/deps/v8/src/arm64/macro-assembler-arm64-inl.h
+++ b/deps/v8/src/arm64/macro-assembler-arm64-inl.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_
#define V8_ARM64_MACRO_ASSEMBLER_ARM64_INL_H_
@@ -319,13 +296,6 @@ LS_MACRO_LIST(DEFINE_FUNCTION)
#undef DEFINE_FUNCTION
-void MacroAssembler::Adr(const Register& rd, Label* label) {
- ASSERT(allow_macro_instructions_);
- ASSERT(!rd.IsZero());
- adr(rd, label);
-}
-
-
void MacroAssembler::Asr(const Register& rd,
const Register& rn,
unsigned shift) {
@@ -833,6 +803,12 @@ void MacroAssembler::Frinta(const FPRegister& fd, const FPRegister& fn) {
}
+void MacroAssembler::Frintm(const FPRegister& fd, const FPRegister& fn) {
+ ASSERT(allow_macro_instructions_);
+ frintm(fd, fn);
+}
+
+
void MacroAssembler::Frintn(const FPRegister& fd, const FPRegister& fn) {
ASSERT(allow_macro_instructions_);
frintn(fd, fn);
@@ -1001,7 +977,6 @@ void MacroAssembler::Mrs(const Register& rt, SystemRegister sysreg) {
void MacroAssembler::Msr(SystemRegister sysreg, const Register& rt) {
ASSERT(allow_macro_instructions_);
- ASSERT(!rt.IsZero());
msr(sysreg, rt);
}
@@ -1409,6 +1384,30 @@ void MacroAssembler::JumpIfBothNotSmi(Register value1,
}
+void MacroAssembler::ObjectTag(Register tagged_obj, Register obj) {
+ STATIC_ASSERT(kHeapObjectTag == 1);
+ if (emit_debug_code()) {
+ Label ok;
+ Tbz(obj, 0, &ok);
+ Abort(kObjectTagged);
+ Bind(&ok);
+ }
+ Orr(tagged_obj, obj, kHeapObjectTag);
+}
+
+
+void MacroAssembler::ObjectUntag(Register untagged_obj, Register obj) {
+ STATIC_ASSERT(kHeapObjectTag == 1);
+ if (emit_debug_code()) {
+ Label ok;
+ Tbnz(obj, 0, &ok);
+ Abort(kObjectNotTagged);
+ Bind(&ok);
+ }
+ Bic(untagged_obj, obj, kHeapObjectTag);
+}
+
+
void MacroAssembler::IsObjectNameType(Register object,
Register type,
Label* fail) {
@@ -1489,12 +1488,9 @@ void MacroAssembler::Claim(uint64_t count, uint64_t unit_size) {
void MacroAssembler::Claim(const Register& count, uint64_t unit_size) {
+ if (unit_size == 0) return;
ASSERT(IsPowerOf2(unit_size));
- if (unit_size == 0) {
- return;
- }
-
const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits);
const Operand size(count, LSL, shift);
@@ -1511,7 +1507,7 @@ void MacroAssembler::Claim(const Register& count, uint64_t unit_size) {
void MacroAssembler::ClaimBySMI(const Register& count_smi, uint64_t unit_size) {
- ASSERT(IsPowerOf2(unit_size));
+ ASSERT(unit_size == 0 || IsPowerOf2(unit_size));
const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift;
const Operand size(count_smi,
(shift >= 0) ? (LSL) : (LSR),
@@ -1550,12 +1546,9 @@ void MacroAssembler::Drop(uint64_t count, uint64_t unit_size) {
void MacroAssembler::Drop(const Register& count, uint64_t unit_size) {
+ if (unit_size == 0) return;
ASSERT(IsPowerOf2(unit_size));
- if (unit_size == 0) {
- return;
- }
-
const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits);
const Operand size(count, LSL, shift);
@@ -1575,7 +1568,7 @@ void MacroAssembler::Drop(const Register& count, uint64_t unit_size) {
void MacroAssembler::DropBySMI(const Register& count_smi, uint64_t unit_size) {
- ASSERT(IsPowerOf2(unit_size));
+ ASSERT(unit_size == 0 || IsPowerOf2(unit_size));
const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift;
const Operand size(count_smi,
(shift >= 0) ? (LSL) : (LSR),
diff --git a/deps/v8/src/arm64/macro-assembler-arm64.cc b/deps/v8/src/arm64/macro-assembler-arm64.cc
index 08ddb8782a..c5ce99be99 100644
--- a/deps/v8/src/arm64/macro-assembler-arm64.cc
+++ b/deps/v8/src/arm64/macro-assembler-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -53,7 +30,9 @@ MacroAssembler::MacroAssembler(Isolate* arg_isolate,
#endif
has_frame_(false),
use_real_aborts_(true),
- sp_(jssp), tmp_list_(ip0, ip1), fptmp_list_(fp_scratch) {
+ sp_(jssp),
+ tmp_list_(DefaultTmpList()),
+ fptmp_list_(DefaultFPTmpList()) {
if (isolate() != NULL) {
code_object_ = Handle<Object>(isolate()->heap()->undefined_value(),
isolate());
@@ -61,13 +40,23 @@ MacroAssembler::MacroAssembler(Isolate* arg_isolate,
}
+CPURegList MacroAssembler::DefaultTmpList() {
+ return CPURegList(ip0, ip1);
+}
+
+
+CPURegList MacroAssembler::DefaultFPTmpList() {
+ return CPURegList(fp_scratch1, fp_scratch2);
+}
+
+
void MacroAssembler::LogicalMacro(const Register& rd,
const Register& rn,
const Operand& operand,
LogicalOp op) {
UseScratchRegisterScope temps(this);
- if (operand.NeedsRelocation()) {
+ if (operand.NeedsRelocation(isolate())) {
Register temp = temps.AcquireX();
LoadRelocated(temp, operand);
Logical(rd, rn, temp, op);
@@ -258,7 +247,7 @@ void MacroAssembler::Mov(const Register& rd,
UseScratchRegisterScope temps(this);
Register dst = (rd.IsSP()) ? temps.AcquireSameSizeAs(rd) : rd;
- if (operand.NeedsRelocation()) {
+ if (operand.NeedsRelocation(isolate())) {
LoadRelocated(dst, operand);
} else if (operand.IsImmediate()) {
@@ -306,7 +295,7 @@ void MacroAssembler::Mov(const Register& rd,
void MacroAssembler::Mvn(const Register& rd, const Operand& operand) {
ASSERT(allow_macro_instructions_);
- if (operand.NeedsRelocation()) {
+ if (operand.NeedsRelocation(isolate())) {
LoadRelocated(rd, operand);
mvn(rd, rd);
@@ -361,7 +350,7 @@ void MacroAssembler::ConditionalCompareMacro(const Register& rn,
Condition cond,
ConditionalCompareOp op) {
ASSERT((cond != al) && (cond != nv));
- if (operand.NeedsRelocation()) {
+ if (operand.NeedsRelocation(isolate())) {
UseScratchRegisterScope temps(this);
Register temp = temps.AcquireX();
LoadRelocated(temp, operand);
@@ -427,12 +416,12 @@ void MacroAssembler::AddSubMacro(const Register& rd,
FlagsUpdate S,
AddSubOp op) {
if (operand.IsZero() && rd.Is(rn) && rd.Is64Bits() && rn.Is64Bits() &&
- !operand.NeedsRelocation() && (S == LeaveFlags)) {
+ !operand.NeedsRelocation(isolate()) && (S == LeaveFlags)) {
// The instruction would be a nop. Avoid generating useless code.
return;
}
- if (operand.NeedsRelocation()) {
+ if (operand.NeedsRelocation(isolate())) {
UseScratchRegisterScope temps(this);
Register temp = temps.AcquireX();
LoadRelocated(temp, operand);
@@ -458,7 +447,7 @@ void MacroAssembler::AddSubWithCarryMacro(const Register& rd,
ASSERT(rd.SizeInBits() == rn.SizeInBits());
UseScratchRegisterScope temps(this);
- if (operand.NeedsRelocation()) {
+ if (operand.NeedsRelocation(isolate())) {
Register temp = temps.AcquireX();
LoadRelocated(temp, operand);
AddSubWithCarryMacro(rd, rn, temp, S, op);
@@ -599,6 +588,43 @@ bool MacroAssembler::NeedExtraInstructionsOrRegisterBranch(
}
+void MacroAssembler::Adr(const Register& rd, Label* label, AdrHint hint) {
+ ASSERT(allow_macro_instructions_);
+ ASSERT(!rd.IsZero());
+
+ if (hint == kAdrNear) {
+ adr(rd, label);
+ return;
+ }
+
+ ASSERT(hint == kAdrFar);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.AcquireX();
+ ASSERT(!AreAliased(rd, scratch));
+
+ if (label->is_bound()) {
+ int label_offset = label->pos() - pc_offset();
+ if (Instruction::IsValidPCRelOffset(label_offset)) {
+ adr(rd, label);
+ } else {
+ ASSERT(label_offset <= 0);
+ int min_adr_offset = -(1 << (Instruction::ImmPCRelRangeBitwidth - 1));
+ adr(rd, min_adr_offset);
+ Add(rd, rd, label_offset - min_adr_offset);
+ }
+ } else {
+ InstructionAccurateScope scope(
+ this, PatchingAssembler::kAdrFarPatchableNInstrs);
+ adr(rd, label);
+ for (int i = 0; i < PatchingAssembler::kAdrFarPatchableNNops; ++i) {
+ nop(ADR_FAR_NOP);
+ }
+ movz(scratch, 0);
+ add(rd, rd, scratch);
+ }
+}
+
+
void MacroAssembler::B(Label* label, BranchType type, Register reg, int bit) {
ASSERT((reg.Is(NoReg) || type >= kBranchTypeFirstUsingReg) &&
(bit == -1 || type >= kBranchTypeFirstUsingBit));
@@ -1196,7 +1222,65 @@ void MacroAssembler::AssertStackConsistency() {
}
-void MacroAssembler::LoadRoot(Register destination,
+void MacroAssembler::AssertFPCRState(Register fpcr) {
+ if (emit_debug_code()) {
+ Label unexpected_mode, done;
+ UseScratchRegisterScope temps(this);
+ if (fpcr.IsNone()) {
+ fpcr = temps.AcquireX();
+ Mrs(fpcr, FPCR);
+ }
+
+ // Settings overridden by ConfiugreFPCR():
+ // - Assert that default-NaN mode is set.
+ Tbz(fpcr, DN_offset, &unexpected_mode);
+
+ // Settings left to their default values:
+ // - Assert that flush-to-zero is not set.
+ Tbnz(fpcr, FZ_offset, &unexpected_mode);
+ // - Assert that the rounding mode is nearest-with-ties-to-even.
+ STATIC_ASSERT(FPTieEven == 0);
+ Tst(fpcr, RMode_mask);
+ B(eq, &done);
+
+ Bind(&unexpected_mode);
+ Abort(kUnexpectedFPCRMode);
+
+ Bind(&done);
+ }
+}
+
+
+void MacroAssembler::ConfigureFPCR() {
+ UseScratchRegisterScope temps(this);
+ Register fpcr = temps.AcquireX();
+ Mrs(fpcr, FPCR);
+
+ // If necessary, enable default-NaN mode. The default values of the other FPCR
+ // options should be suitable, and AssertFPCRState will verify that.
+ Label no_write_required;
+ Tbnz(fpcr, DN_offset, &no_write_required);
+
+ Orr(fpcr, fpcr, DN_mask);
+ Msr(FPCR, fpcr);
+
+ Bind(&no_write_required);
+ AssertFPCRState(fpcr);
+}
+
+
+void MacroAssembler::CanonicalizeNaN(const FPRegister& dst,
+ const FPRegister& src) {
+ AssertFPCRState();
+
+ // With DN=1 and RMode=FPTieEven, subtracting 0.0 preserves all inputs except
+ // for NaNs, which become the default NaN. We use fsub rather than fadd
+ // because sub preserves -0.0 inputs: -0.0 + 0.0 = 0.0, but -0.0 - 0.0 = -0.0.
+ Fsub(dst, src, fp_zero);
+}
+
+
+void MacroAssembler::LoadRoot(CPURegister destination,
Heap::RootListIndex index) {
// TODO(jbramley): Most root values are constants, and can be synthesized
// without a load. Refer to the ARM back end for details.
@@ -1488,9 +1572,9 @@ void MacroAssembler::Throw(BailoutReason reason) {
}
-void MacroAssembler::ThrowIf(Condition cc, BailoutReason reason) {
+void MacroAssembler::ThrowIf(Condition cond, BailoutReason reason) {
Label ok;
- B(InvertCondition(cc), &ok);
+ B(InvertCondition(cond), &ok);
Throw(reason);
Bind(&ok);
}
@@ -1572,12 +1656,12 @@ void MacroAssembler::AssertString(Register object) {
void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) {
ASSERT(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs.
- Call(stub->GetCode(isolate()), RelocInfo::CODE_TARGET, ast_id);
+ Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id);
}
void MacroAssembler::TailCallStub(CodeStub* stub) {
- Jump(stub->GetCode(isolate()), RelocInfo::CODE_TARGET);
+ Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
}
@@ -1589,20 +1673,13 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f,
// Check that the number of arguments matches what the function expects.
// If f->nargs is -1, the function can accept a variable number of arguments.
- if (f->nargs >= 0 && f->nargs != num_arguments) {
- // Illegal operation: drop the stack arguments and return undefined.
- if (num_arguments > 0) {
- Drop(num_arguments);
- }
- LoadRoot(x0, Heap::kUndefinedValueRootIndex);
- return;
- }
+ CHECK(f->nargs < 0 || f->nargs == num_arguments);
// Place the necessary arguments.
Mov(x0, num_arguments);
Mov(x1, ExternalReference(f, isolate()));
- CEntryStub stub(1, save_doubles);
+ CEntryStub stub(isolate(), 1, save_doubles);
CallStub(&stub);
}
@@ -1634,9 +1711,7 @@ void MacroAssembler::CallApiFunctionAndReturn(
Label profiler_disabled;
Label end_profiler_check;
- bool* is_profiling_flag = isolate()->cpu_profiler()->is_profiling_address();
- STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
- Mov(x10, reinterpret_cast<uintptr_t>(is_profiling_flag));
+ Mov(x10, ExternalReference::is_profiling_address(isolate()));
Ldrb(w10, MemOperand(x10));
Cbz(w10, &profiler_disabled);
Mov(x3, thunk_ref);
@@ -1680,7 +1755,7 @@ void MacroAssembler::CallApiFunctionAndReturn(
// Native call returns to the DirectCEntry stub which redirects to the
// return address pushed on stack (could have moved after GC).
// DirectCEntry stub itself is generated early and never moves.
- DirectCEntryStub stub;
+ DirectCEntryStub stub(isolate());
stub.GenerateCall(this, x3);
if (FLAG_log_timer_events) {
@@ -1764,15 +1839,15 @@ void MacroAssembler::CallExternalReference(const ExternalReference& ext,
Mov(x0, num_arguments);
Mov(x1, ext);
- CEntryStub stub(1);
+ CEntryStub stub(isolate(), 1);
CallStub(&stub);
}
void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) {
Mov(x1, builtin);
- CEntryStub stub(1);
- Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
+ CEntryStub stub(isolate(), 1);
+ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
}
@@ -2237,11 +2312,11 @@ void MacroAssembler::LookupNumberStringCache(Register object,
}
-void MacroAssembler::TryConvertDoubleToInt(Register as_int,
- FPRegister value,
- FPRegister scratch_d,
- Label* on_successful_conversion,
- Label* on_failed_conversion) {
+void MacroAssembler::TryRepresentDoubleAsInt(Register as_int,
+ FPRegister value,
+ FPRegister scratch_d,
+ Label* on_successful_conversion,
+ Label* on_failed_conversion) {
// Convert to an int and back again, then compare with the original value.
Fcvtzs(as_int, value);
Scvtf(scratch_d, as_int);
@@ -2870,7 +2945,8 @@ void MacroAssembler::TruncateDoubleToI(Register result,
Push(lr);
Push(double_input); // Put input on stack.
- DoubleToIStub stub(jssp,
+ DoubleToIStub stub(isolate(),
+ jssp,
result,
0,
true, // is_truncating
@@ -2898,7 +2974,8 @@ void MacroAssembler::TruncateHeapNumberToI(Register result,
// If we fell through then inline version didn't succeed - call stub instead.
Push(lr);
- DoubleToIStub stub(object,
+ DoubleToIStub stub(isolate(),
+ object,
result,
HeapNumber::kValueOffset - kHeapObjectTag,
true, // is_truncating
@@ -3135,15 +3212,13 @@ void MacroAssembler::LoadContext(Register dst, int context_chain_length) {
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
void MacroAssembler::DebugBreak() {
Mov(x0, 0);
Mov(x1, ExternalReference(Runtime::kDebugBreak, isolate()));
- CEntryStub ces(1);
+ CEntryStub ces(isolate(), 1);
ASSERT(AllowThisStubCall(&ces));
- Call(ces.GetCode(isolate()), RelocInfo::DEBUG_BREAK);
+ Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
}
-#endif
void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
@@ -3260,14 +3335,13 @@ void MacroAssembler::Allocate(int object_size,
// Calculate new top and bail out if new space is exhausted.
Adds(scratch3, result, object_size);
- B(vs, gc_required);
- Cmp(scratch3, allocation_limit);
+ Ccmp(scratch3, allocation_limit, CFlag, cc);
B(hi, gc_required);
Str(scratch3, MemOperand(top_address));
// Tag the object if requested.
if ((flags & TAG_OBJECT) != 0) {
- Orr(result, result, kHeapObjectTag);
+ ObjectTag(result, result);
}
}
@@ -3342,14 +3416,13 @@ void MacroAssembler::Allocate(Register object_size,
Check(eq, kUnalignedAllocationInNewSpace);
}
- B(vs, gc_required);
- Cmp(scratch3, allocation_limit);
+ Ccmp(scratch3, allocation_limit, CFlag, cc);
B(hi, gc_required);
Str(scratch3, MemOperand(top_address));
// Tag the object if requested.
if ((flags & TAG_OBJECT) != 0) {
- Orr(result, result, kHeapObjectTag);
+ ObjectTag(result, result);
}
}
@@ -3533,32 +3606,50 @@ void MacroAssembler::AllocateHeapNumber(Register result,
Label* gc_required,
Register scratch1,
Register scratch2,
- Register heap_number_map) {
+ CPURegister value,
+ CPURegister heap_number_map) {
+ ASSERT(!value.IsValid() || value.Is64Bits());
+ UseScratchRegisterScope temps(this);
+
// Allocate an object in the heap for the heap number and tag it as a heap
// object.
Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required,
- TAG_OBJECT);
-
- // Store heap number map in the allocated object.
- if (heap_number_map.Is(NoReg)) {
- heap_number_map = scratch1;
+ NO_ALLOCATION_FLAGS);
+
+ // Prepare the heap number map.
+ if (!heap_number_map.IsValid()) {
+ // If we have a valid value register, use the same type of register to store
+ // the map so we can use STP to store both in one instruction.
+ if (value.IsValid() && value.IsFPRegister()) {
+ heap_number_map = temps.AcquireD();
+ } else {
+ heap_number_map = scratch1;
+ }
LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
}
- AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
- Str(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset));
-}
-
+ if (emit_debug_code()) {
+ Register map;
+ if (heap_number_map.IsFPRegister()) {
+ map = scratch1;
+ Fmov(map, DoubleRegister(heap_number_map));
+ } else {
+ map = Register(heap_number_map);
+ }
+ AssertRegisterIsRoot(map, Heap::kHeapNumberMapRootIndex);
+ }
-void MacroAssembler::AllocateHeapNumberWithValue(Register result,
- DoubleRegister value,
- Label* gc_required,
- Register scratch1,
- Register scratch2,
- Register heap_number_map) {
- // TODO(all): Check if it would be more efficient to use STP to store both
- // the map and the value.
- AllocateHeapNumber(result, gc_required, scratch1, scratch2, heap_number_map);
- Str(value, FieldMemOperand(result, HeapNumber::kValueOffset));
+ // Store the heap number map and the value in the allocated object.
+ if (value.IsSameSizeAndType(heap_number_map)) {
+ STATIC_ASSERT(HeapObject::kMapOffset + kPointerSize ==
+ HeapNumber::kValueOffset);
+ Stp(heap_number_map, value, MemOperand(result, HeapObject::kMapOffset));
+ } else {
+ Str(heap_number_map, MemOperand(result, HeapObject::kMapOffset));
+ if (value.IsValid()) {
+ Str(value, MemOperand(result, HeapNumber::kValueOffset));
+ }
+ }
+ ObjectTag(result, result);
}
@@ -3848,7 +3939,6 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
Register elements_reg,
Register scratch1,
FPRegister fpscratch1,
- FPRegister fpscratch2,
Label* fail,
int elements_offset) {
ASSERT(!AreAliased(value_reg, key_reg, elements_reg, scratch1));
@@ -3866,12 +3956,9 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
fail, DONT_DO_SMI_CHECK);
Ldr(fpscratch1, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
- Fmov(fpscratch2, FixedDoubleArray::canonical_not_the_hole_nan_as_double());
- // Check for NaN by comparing the number to itself: NaN comparison will
- // report unordered, indicated by the overflow flag being set.
- Fcmp(fpscratch1, fpscratch1);
- Fcsel(fpscratch1, fpscratch2, fpscratch1, vs);
+ // Canonicalize NaNs.
+ CanonicalizeNaN(fpscratch1);
// Store the result.
Bind(&store_num);
@@ -4136,7 +4223,7 @@ void MacroAssembler::RememberedSetHelper(Register object, // For debug tests.
Bind(&store_buffer_overflow);
Push(lr);
StoreBufferOverflowStub store_buffer_overflow_stub =
- StoreBufferOverflowStub(fp_mode);
+ StoreBufferOverflowStub(isolate(), fp_mode);
CallStub(&store_buffer_overflow_stub);
Pop(lr);
@@ -4329,7 +4416,8 @@ void MacroAssembler::RecordWrite(Register object,
if (lr_status == kLRHasNotBeenSaved) {
Push(lr);
}
- RecordWriteStub stub(object, value, address, remembered_set_action, fp_mode);
+ RecordWriteStub stub(isolate(), object, value, address, remembered_set_action,
+ fp_mode);
CallStub(&stub);
if (lr_status == kLRHasNotBeenSaved) {
Pop(lr);
@@ -4674,8 +4762,7 @@ void MacroAssembler::Abort(BailoutReason reason) {
// We need some scratch registers for the MacroAssembler, so make sure we have
// some. This is safe here because Abort never returns.
RegList old_tmp_list = TmpList()->list();
- TmpList()->Combine(ip0);
- TmpList()->Combine(ip1);
+ TmpList()->Combine(MacroAssembler::DefaultTmpList());
if (use_real_aborts()) {
// Avoid infinite recursion; Push contains some assertions that use Abort.
@@ -4980,7 +5067,8 @@ void MacroAssembler::EmitFrameSetupForCodeAgePatching() {
// TODO(jbramley): Other architectures use the internal memcpy to copy the
// sequence. If this is a performance bottleneck, we should consider caching
// the sequence and copying it in the same way.
- InstructionAccurateScope scope(this, kCodeAgeSequenceSize / kInstructionSize);
+ InstructionAccurateScope scope(this,
+ kNoCodeAgeSequenceLength / kInstructionSize);
ASSERT(jssp.Is(StackPointer()));
EmitFrameSetupForCodeAgePatching(this);
}
@@ -4988,7 +5076,8 @@ void MacroAssembler::EmitFrameSetupForCodeAgePatching() {
void MacroAssembler::EmitCodeAgeSequence(Code* stub) {
- InstructionAccurateScope scope(this, kCodeAgeSequenceSize / kInstructionSize);
+ InstructionAccurateScope scope(this,
+ kNoCodeAgeSequenceLength / kInstructionSize);
ASSERT(jssp.Is(StackPointer()));
EmitCodeAgeSequence(this, stub);
}
@@ -5012,7 +5101,7 @@ void MacroAssembler::EmitFrameSetupForCodeAgePatching(Assembler * assm) {
__ stp(fp, lr, MemOperand(jssp, 2 * kXRegSize));
__ add(fp, jssp, StandardFrameConstants::kFixedFrameSizeFromFp);
- __ AssertSizeOfCodeGeneratedSince(&start, kCodeAgeSequenceSize);
+ __ AssertSizeOfCodeGeneratedSince(&start, kNoCodeAgeSequenceLength);
}
@@ -5035,48 +5124,19 @@ void MacroAssembler::EmitCodeAgeSequence(Assembler * assm,
__ AssertSizeOfCodeGeneratedSince(&start, kCodeAgeStubEntryOffset);
if (stub) {
__ dc64(reinterpret_cast<uint64_t>(stub->instruction_start()));
- __ AssertSizeOfCodeGeneratedSince(&start, kCodeAgeSequenceSize);
+ __ AssertSizeOfCodeGeneratedSince(&start, kNoCodeAgeSequenceLength);
}
}
-bool MacroAssembler::IsYoungSequence(byte* sequence) {
- // Generate a young sequence to compare with.
- const int length = kCodeAgeSequenceSize / kInstructionSize;
- static bool initialized = false;
- static byte young[kCodeAgeSequenceSize];
- if (!initialized) {
- PatchingAssembler patcher(young, length);
- // The young sequence is the frame setup code for FUNCTION code types. It is
- // generated by FullCodeGenerator::Generate.
- MacroAssembler::EmitFrameSetupForCodeAgePatching(&patcher);
- initialized = true;
- }
-
- bool is_young = (memcmp(sequence, young, kCodeAgeSequenceSize) == 0);
- ASSERT(is_young || IsCodeAgeSequence(sequence));
+bool MacroAssembler::IsYoungSequence(Isolate* isolate, byte* sequence) {
+ bool is_young = isolate->code_aging_helper()->IsYoung(sequence);
+ ASSERT(is_young ||
+ isolate->code_aging_helper()->IsOld(sequence));
return is_young;
}
-#ifdef DEBUG
-bool MacroAssembler::IsCodeAgeSequence(byte* sequence) {
- // The old sequence varies depending on the code age. However, the code up
- // until kCodeAgeStubEntryOffset does not change, so we can check that part to
- // get a reasonable level of verification.
- const int length = kCodeAgeStubEntryOffset / kInstructionSize;
- static bool initialized = false;
- static byte old[kCodeAgeStubEntryOffset];
- if (!initialized) {
- PatchingAssembler patcher(old, length);
- MacroAssembler::EmitCodeAgeSequence(&patcher, NULL);
- initialized = true;
- }
- return memcmp(sequence, old, kCodeAgeStubEntryOffset) == 0;
-}
-#endif
-
-
void MacroAssembler::TruncatingDiv(Register result,
Register dividend,
int32_t divisor) {
diff --git a/deps/v8/src/arm64/macro-assembler-arm64.h b/deps/v8/src/arm64/macro-assembler-arm64.h
index 1777c38e35..7d267a2cb0 100644
--- a/deps/v8/src/arm64/macro-assembler-arm64.h
+++ b/deps/v8/src/arm64/macro-assembler-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_MACRO_ASSEMBLER_ARM64_H_
#define V8_ARM64_MACRO_ASSEMBLER_ARM64_H_
@@ -255,8 +232,16 @@ class MacroAssembler : public Assembler {
void Load(const Register& rt, const MemOperand& addr, Representation r);
void Store(const Register& rt, const MemOperand& addr, Representation r);
+ enum AdrHint {
+ // The target must be within the immediate range of adr.
+ kAdrNear,
+ // The target may be outside of the immediate range of adr. Additional
+ // instructions may be emitted.
+ kAdrFar
+ };
+ void Adr(const Register& rd, Label* label, AdrHint = kAdrNear);
+
// Remaining instructions are simple pass-through calls to the assembler.
- inline void Adr(const Register& rd, Label* label);
inline void Asr(const Register& rd, const Register& rn, unsigned shift);
inline void Asr(const Register& rd, const Register& rn, const Register& rm);
@@ -387,6 +372,7 @@ class MacroAssembler : public Assembler {
const FPRegister& fm,
const FPRegister& fa);
inline void Frinta(const FPRegister& fd, const FPRegister& fn);
+ inline void Frintm(const FPRegister& fd, const FPRegister& fn);
inline void Frintn(const FPRegister& fd, const FPRegister& fn);
inline void Frintz(const FPRegister& fd, const FPRegister& fn);
inline void Fsqrt(const FPRegister& fd, const FPRegister& fn);
@@ -502,7 +488,8 @@ class MacroAssembler : public Assembler {
// Pseudo-instructions ------------------------------------------------------
// Compute rd = abs(rm).
- // This function clobbers the condition flags.
+ // This function clobbers the condition flags. On output the overflow flag is
+ // set iff the negation overflowed.
//
// If rm is the minimum representable value, the result is not representable.
// Handlers for each case can be specified using the relevant labels.
@@ -801,8 +788,15 @@ class MacroAssembler : public Assembler {
// Root register.
inline void InitializeRootRegister();
+ void AssertFPCRState(Register fpcr = NoReg);
+ void ConfigureFPCR();
+ void CanonicalizeNaN(const FPRegister& dst, const FPRegister& src);
+ void CanonicalizeNaN(const FPRegister& reg) {
+ CanonicalizeNaN(reg, reg);
+ }
+
// Load an object from the root table.
- void LoadRoot(Register destination,
+ void LoadRoot(CPURegister destination,
Heap::RootListIndex index);
// Store an object to the root table.
void StoreRoot(Register source,
@@ -883,6 +877,9 @@ class MacroAssembler : public Assembler {
void AssertNotSmi(Register object, BailoutReason reason = kOperandIsASmi);
void AssertSmi(Register object, BailoutReason reason = kOperandIsNotASmi);
+ inline void ObjectTag(Register tagged_obj, Register obj);
+ inline void ObjectUntag(Register untagged_obj, Register obj);
+
// Abort execution if argument is not a name, enabled via --debug-code.
void AssertName(Register object);
@@ -932,34 +929,34 @@ class MacroAssembler : public Assembler {
DoubleRegister input,
DoubleRegister dbl_scratch);
- // Try to convert a double to a signed 32-bit int.
+ // Try to represent a double as a signed 32-bit int.
// This succeeds if the result compares equal to the input, so inputs of -0.0
- // are converted to 0 and handled as a success.
- //
- // On output the Z flag is set if the conversion was successful.
- void TryConvertDoubleToInt32(Register as_int,
- FPRegister value,
- FPRegister scratch_d,
- Label* on_successful_conversion = NULL,
- Label* on_failed_conversion = NULL) {
+ // are represented as 0 and handled as a success.
+ //
+ // On output the Z flag is set if the operation was successful.
+ void TryRepresentDoubleAsInt32(Register as_int,
+ FPRegister value,
+ FPRegister scratch_d,
+ Label* on_successful_conversion = NULL,
+ Label* on_failed_conversion = NULL) {
ASSERT(as_int.Is32Bits());
- TryConvertDoubleToInt(as_int, value, scratch_d, on_successful_conversion,
- on_failed_conversion);
+ TryRepresentDoubleAsInt(as_int, value, scratch_d, on_successful_conversion,
+ on_failed_conversion);
}
- // Try to convert a double to a signed 64-bit int.
+ // Try to represent a double as a signed 64-bit int.
// This succeeds if the result compares equal to the input, so inputs of -0.0
- // are converted to 0 and handled as a success.
- //
- // On output the Z flag is set if the conversion was successful.
- void TryConvertDoubleToInt64(Register as_int,
- FPRegister value,
- FPRegister scratch_d,
- Label* on_successful_conversion = NULL,
- Label* on_failed_conversion = NULL) {
+ // are represented as 0 and handled as a success.
+ //
+ // On output the Z flag is set if the operation was successful.
+ void TryRepresentDoubleAsInt64(Register as_int,
+ FPRegister value,
+ FPRegister scratch_d,
+ Label* on_successful_conversion = NULL,
+ Label* on_failed_conversion = NULL) {
ASSERT(as_int.Is64Bits());
- TryConvertDoubleToInt(as_int, value, scratch_d, on_successful_conversion,
- on_failed_conversion);
+ TryRepresentDoubleAsInt(as_int, value, scratch_d, on_successful_conversion,
+ on_failed_conversion);
}
// ---- Object Utilities ----
@@ -1055,7 +1052,7 @@ class MacroAssembler : public Assembler {
void Throw(BailoutReason reason);
// Throw a message string as an exception if a condition is not true.
- void ThrowIf(Condition cc, BailoutReason reason);
+ void ThrowIf(Condition cond, BailoutReason reason);
// Throw a message string as an exception if the value is a smi.
void ThrowIfSmi(const Register& value, BailoutReason reason);
@@ -1265,12 +1262,11 @@ class MacroAssembler : public Assembler {
MacroAssembler* masm_;
};
-#ifdef ENABLE_DEBUGGER_SUPPORT
// ---------------------------------------------------------------------------
// Debugger Support
void DebugBreak();
-#endif
+
// ---------------------------------------------------------------------------
// Exception handling
@@ -1354,13 +1350,8 @@ class MacroAssembler : public Assembler {
Label* gc_required,
Register scratch1,
Register scratch2,
- Register heap_number_map = NoReg);
- void AllocateHeapNumberWithValue(Register result,
- DoubleRegister value,
- Label* gc_required,
- Register scratch1,
- Register scratch2,
- Register heap_number_map = NoReg);
+ CPURegister value = NoFPReg,
+ CPURegister heap_number_map = NoReg);
// ---------------------------------------------------------------------------
// Support functions.
@@ -1549,7 +1540,6 @@ class MacroAssembler : public Assembler {
Register elements_reg,
Register scratch1,
FPRegister fpscratch1,
- FPRegister fpscratch2,
Label* fail,
int elements_offset = 0);
@@ -1919,6 +1909,9 @@ class MacroAssembler : public Assembler {
CPURegList* TmpList() { return &tmp_list_; }
CPURegList* FPTmpList() { return &fptmp_list_; }
+ static CPURegList DefaultTmpList();
+ static CPURegList DefaultFPTmpList();
+
// Like printf, but print at run-time from generated code.
//
// The caller must ensure that arguments for floating-point placeholders
@@ -1939,10 +1932,6 @@ class MacroAssembler : public Assembler {
// PrintfNoPreserve. Callee-saved registers are not used by Printf, and are
// implicitly preserved.
//
- // Unlike many MacroAssembler functions, x8 and x9 are guaranteed to be
- // preserved, and can be printed. This allows Printf to be used during debug
- // code.
- //
// This function assumes (and asserts) that the current stack pointer is
// callee-saved, not caller-saved. This is most likely the case anyway, as a
// caller-saved stack pointer doesn't make a lot of sense.
@@ -1998,13 +1987,7 @@ class MacroAssembler : public Assembler {
// Return true if the sequence is a young sequence geneated by
// EmitFrameSetupForCodeAgePatching. Otherwise, this method asserts that the
// sequence is a code age sequence (emitted by EmitCodeAgeSequence).
- static bool IsYoungSequence(byte* sequence);
-
-#ifdef DEBUG
- // Return true if the sequence is a code age sequence generated by
- // EmitCodeAgeSequence.
- static bool IsCodeAgeSequence(byte* sequence);
-#endif
+ static bool IsYoungSequence(Isolate* isolate, byte* sequence);
// Jumps to found label if a prototype map has dictionary elements.
void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0,
@@ -2067,7 +2050,7 @@ class MacroAssembler : public Assembler {
Condition cond, // eq for new space, ne otherwise.
Label* branch);
- // Try to convert a double to an int so that integer fast-paths may be
+ // Try to represent a double as an int so that integer fast-paths may be
// used. Not every valid integer value is guaranteed to be caught.
// It supports both 32-bit and 64-bit integers depending whether 'as_int'
// is a W or X register.
@@ -2075,12 +2058,12 @@ class MacroAssembler : public Assembler {
// This does not distinguish between +0 and -0, so if this distinction is
// important it must be checked separately.
//
- // On output the Z flag is set if the conversion was successful.
- void TryConvertDoubleToInt(Register as_int,
- FPRegister value,
- FPRegister scratch_d,
- Label* on_successful_conversion = NULL,
- Label* on_failed_conversion = NULL);
+ // On output the Z flag is set if the operation was successful.
+ void TryRepresentDoubleAsInt(Register as_int,
+ FPRegister value,
+ FPRegister scratch_d,
+ Label* on_successful_conversion = NULL,
+ Label* on_failed_conversion = NULL);
bool generating_stub_;
#if DEBUG
diff --git a/deps/v8/src/arm64/regexp-macro-assembler-arm64.cc b/deps/v8/src/arm64/regexp-macro-assembler-arm64.cc
index 536580ab55..97040cf75e 100644
--- a/deps/v8/src/arm64/regexp-macro-assembler-arm64.cc
+++ b/deps/v8/src/arm64/regexp-macro-assembler-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -1128,7 +1105,7 @@ void RegExpMacroAssemblerARM64::PushBacktrack(Label* label) {
int target = label->pos();
__ Mov(w10, target + Code::kHeaderSize - kHeapObjectTag);
} else {
- __ Adr(x10, label);
+ __ Adr(x10, label, MacroAssembler::kAdrFar);
__ Sub(x10, x10, code_pointer());
if (masm_->emit_debug_code()) {
__ Cmp(x10, kWRegMask);
@@ -1338,7 +1315,7 @@ int RegExpMacroAssemblerARM64::CheckStackGuardState(Address* return_address,
ASSERT(*return_address <=
re_code->instruction_start() + re_code->instruction_size());
- MaybeObject* result = Execution::HandleStackGuardInterrupt(isolate);
+ Object* result = Execution::HandleStackGuardInterrupt(isolate);
if (*code_handle != re_code) { // Return address no longer valid
int delta = code_handle->address() - re_code->address();
@@ -1454,7 +1431,7 @@ void RegExpMacroAssemblerARM64::CallCheckStackGuardState(Register scratch) {
ExternalReference check_stack_guard_state =
ExternalReference::re_check_stack_guard_state(isolate());
__ Mov(scratch, check_stack_guard_state);
- DirectCEntryStub stub;
+ DirectCEntryStub stub(isolate());
stub.GenerateCall(masm_, scratch);
// The input string may have been moved in memory, we need to reload it.
diff --git a/deps/v8/src/arm64/regexp-macro-assembler-arm64.h b/deps/v8/src/arm64/regexp-macro-assembler-arm64.h
index 534fd5b01a..5d0d925ecc 100644
--- a/deps/v8/src/arm64/regexp-macro-assembler-arm64.h
+++ b/deps/v8/src/arm64/regexp-macro-assembler-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_REGEXP_MACRO_ASSEMBLER_ARM64_H_
#define V8_ARM64_REGEXP_MACRO_ASSEMBLER_ARM64_H_
diff --git a/deps/v8/src/arm64/simulator-arm64.cc b/deps/v8/src/arm64/simulator-arm64.cc
index cd475b40e1..3c970f854a 100644
--- a/deps/v8/src/arm64/simulator-arm64.cc
+++ b/deps/v8/src/arm64/simulator-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <stdlib.h>
#include <cmath>
@@ -80,11 +57,11 @@ TEXT_COLOUR clr_printf = FLAG_log_colour ? COLOUR(GREEN) : "";
// This is basically the same as PrintF, with a guard for FLAG_trace_sim.
-void PRINTF_CHECKING TraceSim(const char* format, ...) {
+void Simulator::TraceSim(const char* format, ...) {
if (FLAG_trace_sim) {
va_list arguments;
va_start(arguments, format);
- OS::VPrint(format, arguments);
+ OS::VFPrint(stream_, format, arguments);
va_end(arguments);
}
}
@@ -392,7 +369,7 @@ Simulator::Simulator()
last_debugger_input_(NULL),
log_parameters_(NO_PARAM),
isolate_(NULL) {
- Init(NULL);
+ Init(stdout);
CHECK(!FLAG_trace_sim && !FLAG_log_instruction_stats);
}
@@ -593,7 +570,7 @@ void Simulator::DoRuntimeCall(Instruction* instr) {
break;
case ExternalReference::BUILTIN_CALL: {
- // MaybeObject* f(v8::internal::Arguments).
+ // Object* f(v8::internal::Arguments).
TraceSim("Type: BUILTIN_CALL\n");
SimulatorRuntimeCall target =
reinterpret_cast<SimulatorRuntimeCall>(external);
@@ -1001,7 +978,8 @@ void Simulator::FPCompare(double val0, double val1) {
void Simulator::SetBreakpoint(Instruction* location) {
for (unsigned i = 0; i < breakpoints_.size(); i++) {
if (breakpoints_.at(i).location == location) {
- PrintF("Existing breakpoint at %p was %s\n",
+ PrintF(stream_,
+ "Existing breakpoint at %p was %s\n",
reinterpret_cast<void*>(location),
breakpoints_.at(i).enabled ? "disabled" : "enabled");
breakpoints_.at(i).enabled = !breakpoints_.at(i).enabled;
@@ -1010,14 +988,15 @@ void Simulator::SetBreakpoint(Instruction* location) {
}
Breakpoint new_breakpoint = {location, true};
breakpoints_.push_back(new_breakpoint);
- PrintF("Set a breakpoint at %p\n", reinterpret_cast<void*>(location));
+ PrintF(stream_,
+ "Set a breakpoint at %p\n", reinterpret_cast<void*>(location));
}
void Simulator::ListBreakpoints() {
- PrintF("Breakpoints:\n");
+ PrintF(stream_, "Breakpoints:\n");
for (unsigned i = 0; i < breakpoints_.size(); i++) {
- PrintF("%p : %s\n",
+ PrintF(stream_, "%p : %s\n",
reinterpret_cast<void*>(breakpoints_.at(i).location),
breakpoints_.at(i).enabled ? "enabled" : "disabled");
}
@@ -1035,7 +1014,7 @@ void Simulator::CheckBreakpoints() {
}
}
if (hit_a_breakpoint) {
- PrintF("Hit and disabled a breakpoint at %p.\n",
+ PrintF(stream_, "Hit and disabled a breakpoint at %p.\n",
reinterpret_cast<void*>(pc_));
Debug();
}
@@ -2000,7 +1979,8 @@ void Simulator::VisitDataProcessing2Source(Instruction* instr) {
if (shift_op != NO_SHIFT) {
// Shift distance encoded in the least-significant five/six bits of the
// register.
- int mask = (instr->SixtyFourBits() == 1) ? 0x3f : 0x1f;
+ int mask = (instr->SixtyFourBits() == 1) ? kShiftAmountXRegMask
+ : kShiftAmountWRegMask;
unsigned shift = wreg(instr->Rm()) & mask;
result = ShiftOperand(reg_size, reg(reg_size, instr->Rn()), shift_op,
shift);
@@ -2108,8 +2088,9 @@ void Simulator::VisitBitfield(Instruction* instr) {
// Rotate source bitfield into place.
int64_t result = (static_cast<uint64_t>(src) >> R) | (src << (reg_size - R));
// Determine the sign extension.
- int64_t topbits = ((1L << (reg_size - diff - 1)) - 1) << (diff + 1);
- int64_t signbits = extend && ((src >> S) & 1) ? topbits : 0;
+ int64_t topbits_preshift = (1L << (reg_size - diff - 1)) - 1;
+ int64_t signbits = (extend && ((src >> S) & 1) ? topbits_preshift : 0)
+ << (diff + 1);
// Merge sign extension, dest/zero and bitfield.
result = signbits | (result & mask) | (dst & ~mask);
@@ -2389,6 +2370,10 @@ void Simulator::VisitFPDataProcessing1Source(Instruction* instr) {
case FSQRT_d: set_dreg(fd, FPSqrt(dreg(fn))); break;
case FRINTA_s: set_sreg(fd, FPRoundInt(sreg(fn), FPTieAway)); break;
case FRINTA_d: set_dreg(fd, FPRoundInt(dreg(fn), FPTieAway)); break;
+ case FRINTM_s:
+ set_sreg(fd, FPRoundInt(sreg(fn), FPNegativeInfinity)); break;
+ case FRINTM_d:
+ set_dreg(fd, FPRoundInt(dreg(fn), FPNegativeInfinity)); break;
case FRINTN_s: set_sreg(fd, FPRoundInt(sreg(fn), FPTieEven)); break;
case FRINTN_d: set_dreg(fd, FPRoundInt(dreg(fn), FPTieEven)); break;
case FRINTZ_s: set_sreg(fd, FPRoundInt(sreg(fn), FPZero)); break;
@@ -2655,17 +2640,27 @@ double Simulator::FPRoundInt(double value, FPRounding round_mode) {
double error = value - int_result;
switch (round_mode) {
case FPTieAway: {
- // If the error is greater than 0.5, or is equal to 0.5 and the integer
- // result is positive, round up.
- if ((error > 0.5) || ((error == 0.5) && (int_result >= 0.0))) {
+ // Take care of correctly handling the range ]-0.5, -0.0], which must
+ // yield -0.0.
+ if ((-0.5 < value) && (value < 0.0)) {
+ int_result = -0.0;
+
+ } else if ((error > 0.5) || ((error == 0.5) && (int_result >= 0.0))) {
+ // If the error is greater than 0.5, or is equal to 0.5 and the integer
+ // result is positive, round up.
int_result++;
}
break;
}
case FPTieEven: {
+ // Take care of correctly handling the range [-0.5, -0.0], which must
+ // yield -0.0.
+ if ((-0.5 <= value) && (value < 0.0)) {
+ int_result = -0.0;
+
// If the error is greater than 0.5, or is equal to 0.5 and the integer
// result is odd, round up.
- if ((error > 0.5) ||
+ } else if ((error > 0.5) ||
((error == 0.5) && (fmod(int_result, 2) != 0))) {
int_result++;
}
@@ -3166,12 +3161,12 @@ bool Simulator::GetValue(const char* desc, int64_t* value) {
bool Simulator::PrintValue(const char* desc) {
if (strcmp(desc, "csp") == 0) {
ASSERT(CodeFromName(desc) == static_cast<int>(kSPRegInternalCode));
- PrintF("%s csp:%s 0x%016" PRIx64 "%s\n",
+ PrintF(stream_, "%s csp:%s 0x%016" PRIx64 "%s\n",
clr_reg_name, clr_reg_value, xreg(31, Reg31IsStackPointer), clr_normal);
return true;
} else if (strcmp(desc, "wcsp") == 0) {
ASSERT(CodeFromName(desc) == static_cast<int>(kSPRegInternalCode));
- PrintF("%s wcsp:%s 0x%08" PRIx32 "%s\n",
+ PrintF(stream_, "%s wcsp:%s 0x%08" PRIx32 "%s\n",
clr_reg_name, clr_reg_value, wreg(31, Reg31IsStackPointer), clr_normal);
return true;
}
@@ -3181,7 +3176,7 @@ bool Simulator::PrintValue(const char* desc) {
if (i < 0 || static_cast<unsigned>(i) >= kNumberOfFPRegisters) return false;
if (desc[0] == 'v') {
- PrintF("%s %s:%s 0x%016" PRIx64 "%s (%s%s:%s %g%s %s:%s %g%s)\n",
+ PrintF(stream_, "%s %s:%s 0x%016" PRIx64 "%s (%s%s:%s %g%s %s:%s %g%s)\n",
clr_fpreg_name, VRegNameForCode(i),
clr_fpreg_value, double_to_rawbits(dreg(i)),
clr_normal,
@@ -3192,25 +3187,25 @@ bool Simulator::PrintValue(const char* desc) {
clr_normal);
return true;
} else if (desc[0] == 'd') {
- PrintF("%s %s:%s %g%s\n",
+ PrintF(stream_, "%s %s:%s %g%s\n",
clr_fpreg_name, DRegNameForCode(i),
clr_fpreg_value, dreg(i),
clr_normal);
return true;
} else if (desc[0] == 's') {
- PrintF("%s %s:%s %g%s\n",
+ PrintF(stream_, "%s %s:%s %g%s\n",
clr_fpreg_name, SRegNameForCode(i),
clr_fpreg_value, sreg(i),
clr_normal);
return true;
} else if (desc[0] == 'w') {
- PrintF("%s %s:%s 0x%08" PRIx32 "%s\n",
+ PrintF(stream_, "%s %s:%s 0x%08" PRIx32 "%s\n",
clr_reg_name, WRegNameForCode(i), clr_reg_value, wreg(i), clr_normal);
return true;
} else {
// X register names have a wide variety of starting characters, but anything
// else will be an X register.
- PrintF("%s %s:%s 0x%016" PRIx64 "%s\n",
+ PrintF(stream_, "%s %s:%s 0x%016" PRIx64 "%s\n",
clr_reg_name, XRegNameForCode(i), clr_reg_value, xreg(i), clr_normal);
return true;
}
@@ -3529,14 +3524,16 @@ void Simulator::VisitException(Instruction* instr) {
// terms of speed.
if (FLAG_trace_sim_messages || FLAG_trace_sim || (parameters & BREAK)) {
if (message != NULL) {
- PrintF("%sDebugger hit %d: %s%s%s\n",
+ PrintF(stream_,
+ "%sDebugger hit %d: %s%s%s\n",
clr_debug_number,
code,
clr_debug_message,
message,
clr_normal);
} else {
- PrintF("%sDebugger hit %d.%s\n",
+ PrintF(stream_,
+ "%sDebugger hit %d.%s\n",
clr_debug_number,
code,
clr_normal);
diff --git a/deps/v8/src/arm64/simulator-arm64.h b/deps/v8/src/arm64/simulator-arm64.h
index 6a7353b461..543385b376 100644
--- a/deps/v8/src/arm64/simulator-arm64.h
+++ b/deps/v8/src/arm64/simulator-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_SIMULATOR_ARM64_H_
#define V8_ARM64_SIMULATOR_ARM64_H_
@@ -785,6 +762,7 @@ class Simulator : public DecoderVisitor {
// Output stream.
FILE* stream_;
PrintDisassembler* print_disasm_;
+ void PRINTF_METHOD_CHECKING TraceSim(const char* format, ...);
// Instrumentation.
Instrument* instrument_;
diff --git a/deps/v8/src/arm64/stub-cache-arm64.cc b/deps/v8/src/arm64/stub-cache-arm64.cc
index 1b2e959936..760fbb3540 100644
--- a/deps/v8/src/arm64/stub-cache-arm64.cc
+++ b/deps/v8/src/arm64/stub-cache-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -393,14 +370,28 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
__ JumpIfSmi(value_reg, miss_label);
+ HeapType* field_type = descriptors->GetFieldType(descriptor);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ while (true) {
+ __ CompareMap(scratch1, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ B(ne, miss_label);
+ break;
+ }
+ __ B(eq, &do_store);
+ }
+ __ Bind(&do_store);
+ }
} else if (representation.IsDouble()) {
UseScratchRegisterScope temps(masm);
DoubleRegister temp_double = temps.AcquireD();
__ SmiUntagToDouble(temp_double, value_reg, kSpeculativeUntag);
- Label do_store, heap_number;
- __ AllocateHeapNumber(storage_reg, slow, scratch1, scratch2);
-
+ Label do_store;
__ JumpIfSmi(value_reg, &do_store);
__ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex,
@@ -408,7 +399,7 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
__ Ldr(temp_double, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
__ Bind(&do_store);
- __ Str(temp_double, FieldMemOperand(storage_reg, HeapNumber::kValueOffset));
+ __ AllocateHeapNumber(storage_reg, slow, scratch1, scratch2, temp_double);
}
// Stub never generated for non-global objects that require access checks.
@@ -544,6 +535,22 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
__ JumpIfSmi(value_reg, miss_label);
+ HeapType* field_type = lookup->GetFieldType();
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ while (true) {
+ __ CompareMap(scratch1, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ B(ne, miss_label);
+ break;
+ }
+ __ B(eq, &do_store);
+ }
+ __ Bind(&do_store);
+ }
} else if (representation.IsDouble()) {
UseScratchRegisterScope temps(masm);
DoubleRegister temp_double = temps.AcquireD();
@@ -755,7 +762,7 @@ void StubCompiler::GenerateFastApiCall(MacroAssembler* masm,
__ Mov(api_function_address, ref);
// Jump to stub.
- CallApiFunctionStub stub(is_store, call_data_undefined, argc);
+ CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
__ TailCallStub(&stub);
}
@@ -790,7 +797,7 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
Handle<JSObject> current = Handle<JSObject>::null();
if (type->IsConstant()) {
- current = Handle<JSObject>::cast(type->AsConstant());
+ current = Handle<JSObject>::cast(type->AsConstant()->Value());
}
Handle<JSObject> prototype = Handle<JSObject>::null();
Handle<Map> current_map = receiver_map;
@@ -814,7 +821,7 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
name = factory()->InternalizeString(Handle<String>::cast(name));
}
ASSERT(current.is_null() ||
- (current->property_dictionary()->FindEntry(*name) ==
+ (current->property_dictionary()->FindEntry(name) ==
NameDictionary::kNotFound));
GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
@@ -964,15 +971,17 @@ void LoadStubCompiler::GenerateLoadField(Register reg,
Representation representation) {
__ Mov(receiver(), reg);
if (kind() == Code::LOAD_IC) {
- LoadFieldStub stub(field.is_inobject(holder),
+ LoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
field.translate(holder),
representation);
- GenerateTailCall(masm(), stub.GetCode(isolate()));
+ GenerateTailCall(masm(), stub.GetCode());
} else {
- KeyedLoadFieldStub stub(field.is_inobject(holder),
+ KeyedLoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
field.translate(holder),
representation);
- GenerateTailCall(masm(), stub.GetCode(isolate()));
+ GenerateTailCall(masm(), stub.GetCode());
}
}
@@ -1034,7 +1043,7 @@ void LoadStubCompiler::GenerateLoadCallback(
ExternalReference ref = ExternalReference(&fun, type, isolate());
__ Mov(getter_address_reg, ref);
- CallApiGetterStub stub;
+ CallApiGetterStub stub(isolate());
__ TailCallStub(&stub);
}
@@ -1127,19 +1136,6 @@ void LoadStubCompiler::GenerateLoadInterceptor(
}
-void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
- UseScratchRegisterScope temps(masm());
- // Check that the object is a boolean.
- Register true_root = temps.AcquireX();
- Register false_root = temps.AcquireX();
- ASSERT(!AreAliased(object, true_root, false_root));
- __ LoadTrueFalseRoots(true_root, false_root);
- __ Cmp(object, true_root);
- __ Ccmp(object, false_root, ZFlag, ne);
- __ B(ne, miss);
-}
-
-
Handle<Code> StoreStubCompiler::CompileStoreCallback(
Handle<JSObject> object,
Handle<JSObject> holder,
diff --git a/deps/v8/src/arm64/utils-arm64.cc b/deps/v8/src/arm64/utils-arm64.cc
index e2589f42e8..53a2957e91 100644
--- a/deps/v8/src/arm64/utils-arm64.cc
+++ b/deps/v8/src/arm64/utils-arm64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#if V8_TARGET_ARCH_ARM64
diff --git a/deps/v8/src/arm64/utils-arm64.h b/deps/v8/src/arm64/utils-arm64.h
index a1fa12cfa7..c739e50f26 100644
--- a/deps/v8/src/arm64/utils-arm64.h
+++ b/deps/v8/src/arm64/utils-arm64.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ARM64_UTILS_ARM64_H_
#define V8_ARM64_UTILS_ARM64_H_
diff --git a/deps/v8/src/array-iterator.js b/deps/v8/src/array-iterator.js
index 3af659dbcc..10116b1d10 100644
--- a/deps/v8/src/array-iterator.js
+++ b/deps/v8/src/array-iterator.js
@@ -31,11 +31,6 @@
// in runtime.js:
// var $Array = global.Array;
-var ARRAY_ITERATOR_KIND_KEYS = 1;
-var ARRAY_ITERATOR_KIND_VALUES = 2;
-var ARRAY_ITERATOR_KIND_ENTRIES = 3;
-// The spec draft also has "sparse" but it is never used.
-
var arrayIteratorObjectSymbol = GLOBAL_PRIVATE("ArrayIterator#object");
var arrayIteratorNextIndexSymbol = GLOBAL_PRIVATE("ArrayIterator#next");
var arrayIterationKindSymbol = GLOBAL_PRIVATE("ArrayIterator#kind");
@@ -79,25 +74,25 @@ function ArrayIteratorNext() {
SET_PRIVATE(iterator, arrayIteratorNextIndexSymbol, index + 1);
- if (itemKind == ARRAY_ITERATOR_KIND_VALUES)
+ if (itemKind == ITERATOR_KIND_VALUES)
return CreateIteratorResultObject(array[index], false);
- if (itemKind == ARRAY_ITERATOR_KIND_ENTRIES)
+ if (itemKind == ITERATOR_KIND_ENTRIES)
return CreateIteratorResultObject([index, array[index]], false);
return CreateIteratorResultObject(index, false);
}
function ArrayEntries() {
- return CreateArrayIterator(this, ARRAY_ITERATOR_KIND_ENTRIES);
+ return CreateArrayIterator(this, ITERATOR_KIND_ENTRIES);
}
function ArrayValues() {
- return CreateArrayIterator(this, ARRAY_ITERATOR_KIND_VALUES);
+ return CreateArrayIterator(this, ITERATOR_KIND_VALUES);
}
function ArrayKeys() {
- return CreateArrayIterator(this, ARRAY_ITERATOR_KIND_KEYS);
+ return CreateArrayIterator(this, ITERATOR_KIND_KEYS);
}
function SetUpArrayIterator() {
diff --git a/deps/v8/src/array.js b/deps/v8/src/array.js
index e48230e2bd..dcaf0f4008 100644
--- a/deps/v8/src/array.js
+++ b/deps/v8/src/array.js
@@ -1,29 +1,8 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+"use strict";
// This file relies on the fact that the following declarations have been made
// in runtime.js:
@@ -378,17 +357,18 @@ function ArrayToLocaleString() {
function ArrayJoin(separator) {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.join");
- var length = TO_UINT32(this.length);
+ var array = TO_OBJECT_INLINE(this);
+ var length = TO_UINT32(array.length);
if (IS_UNDEFINED(separator)) {
separator = ',';
} else if (!IS_STRING(separator)) {
separator = NonStringToString(separator);
}
- var result = %_FastAsciiArrayJoin(this, separator);
+ var result = %_FastAsciiArrayJoin(array, separator);
if (!IS_UNDEFINED(result)) return result;
- return Join(this, length, separator, ConvertToString);
+ return Join(array, length, separator, ConvertToString);
}
@@ -413,24 +393,20 @@ function ObservedArrayPop(n) {
function ArrayPop() {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.pop");
- var n = TO_UINT32(this.length);
+ var array = TO_OBJECT_INLINE(this);
+ var n = TO_UINT32(array.length);
if (n == 0) {
- this.length = n;
+ array.length = n;
return;
}
- if ($Object.isSealed(this)) {
- throw MakeTypeError("array_functions_change_sealed",
- ["Array.prototype.pop"]);
- }
-
- if (%IsObserved(this))
- return ObservedArrayPop.call(this, n);
+ if (%IsObserved(array))
+ return ObservedArrayPop.call(array, n);
n--;
- var value = this[n];
- Delete(this, ToName(n), true);
- this.length = n;
+ var value = array[n];
+ Delete(array, ToName(n), true);
+ array.length = n;
return value;
}
@@ -444,13 +420,14 @@ function ObservedArrayPush() {
for (var i = 0; i < m; i++) {
this[i+n] = %_Arguments(i);
}
- this.length = n + m;
+ var new_length = n + m;
+ this.length = new_length;
} finally {
EndPerformSplice(this);
EnqueueSpliceRecord(this, n, [], m);
}
- return this.length;
+ return new_length;
}
// Appends the arguments to the end of the array and returns the new
@@ -458,21 +435,22 @@ function ObservedArrayPush() {
function ArrayPush() {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push");
- var n = TO_UINT32(this.length);
- var m = %_ArgumentsLength();
- if (m > 0 && $Object.isSealed(this)) {
- throw MakeTypeError("array_functions_change_sealed",
- ["Array.prototype.push"]);
- }
-
if (%IsObserved(this))
return ObservedArrayPush.apply(this, arguments);
+ var array = TO_OBJECT_INLINE(this);
+ var n = TO_UINT32(array.length);
+ var m = %_ArgumentsLength();
+
for (var i = 0; i < m; i++) {
- this[i+n] = %_Arguments(i);
+ // Use SetProperty rather than a direct keyed store to ensure that the store
+ // site doesn't become poisened with an elements transition KeyedStoreIC.
+ %SetProperty(array, i+n, %_Arguments(i), 0, kStrictMode);
}
- this.length = n + m;
- return this.length;
+
+ var new_length = n + m;
+ array.length = new_length;
+ return new_length;
}
@@ -541,33 +519,34 @@ function SparseReverse(array, len) {
function ArrayReverse() {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reverse");
- var j = TO_UINT32(this.length) - 1;
+ var array = TO_OBJECT_INLINE(this);
+ var j = TO_UINT32(array.length) - 1;
- if (UseSparseVariant(this, j, IS_ARRAY(this))) {
- SparseReverse(this, j+1);
- return this;
+ if (UseSparseVariant(array, j, IS_ARRAY(array))) {
+ SparseReverse(array, j+1);
+ return array;
}
for (var i = 0; i < j; i++, j--) {
- var current_i = this[i];
- if (!IS_UNDEFINED(current_i) || i in this) {
- var current_j = this[j];
- if (!IS_UNDEFINED(current_j) || j in this) {
- this[i] = current_j;
- this[j] = current_i;
+ var current_i = array[i];
+ if (!IS_UNDEFINED(current_i) || i in array) {
+ var current_j = array[j];
+ if (!IS_UNDEFINED(current_j) || j in array) {
+ array[i] = current_j;
+ array[j] = current_i;
} else {
- this[j] = current_i;
- delete this[i];
+ array[j] = current_i;
+ delete array[i];
}
} else {
- var current_j = this[j];
- if (!IS_UNDEFINED(current_j) || j in this) {
- this[i] = current_j;
- delete this[j];
+ var current_j = array[j];
+ if (!IS_UNDEFINED(current_j) || j in array) {
+ array[i] = current_j;
+ delete array[j];
}
}
}
- return this;
+ return array;
}
@@ -589,30 +568,31 @@ function ObservedArrayShift(len) {
function ArrayShift() {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.shift");
- var len = TO_UINT32(this.length);
+ var array = TO_OBJECT_INLINE(this);
+ var len = TO_UINT32(array.length);
if (len === 0) {
- this.length = 0;
+ array.length = 0;
return;
}
- if ($Object.isSealed(this)) {
+ if (ObjectIsSealed(array)) {
throw MakeTypeError("array_functions_change_sealed",
["Array.prototype.shift"]);
}
- if (%IsObserved(this))
- return ObservedArrayShift.call(this, len);
+ if (%IsObserved(array))
+ return ObservedArrayShift.call(array, len);
- var first = this[0];
+ var first = array[0];
- if (IS_ARRAY(this)) {
- SmartMove(this, 0, 1, len, 0);
+ if (IS_ARRAY(array)) {
+ SmartMove(array, 0, 1, len, 0);
} else {
- SimpleMove(this, 0, 1, len, 0);
+ SimpleMove(array, 0, 1, len, 0);
}
- this.length = len - 1;
+ array.length = len - 1;
return first;
}
@@ -627,61 +607,48 @@ function ObservedArrayUnshift() {
for (var i = 0; i < num_arguments; i++) {
this[i] = %_Arguments(i);
}
- this.length = len + num_arguments;
+ var new_length = len + num_arguments;
+ this.length = new_length;
} finally {
EndPerformSplice(this);
EnqueueSpliceRecord(this, 0, [], num_arguments);
}
- return len + num_arguments;
+ return new_length;
}
function ArrayUnshift(arg1) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift");
- var len = TO_UINT32(this.length);
- var num_arguments = %_ArgumentsLength();
- var is_sealed = $Object.isSealed(this);
-
- if (num_arguments > 0 && is_sealed) {
- throw MakeTypeError("array_functions_change_sealed",
- ["Array.prototype.unshift"]);
- }
-
if (%IsObserved(this))
return ObservedArrayUnshift.apply(this, arguments);
- if (IS_ARRAY(this) && !is_sealed) {
- SmartMove(this, 0, 0, len, num_arguments);
- } else {
- if (num_arguments == 0 && $Object.isFrozen(this)) {
- // In the zero argument case, values from the prototype come into the
- // object. This can't be allowed on frozen arrays.
- for (var i = 0; i < len; i++) {
- if (!this.hasOwnProperty(i) && !IS_UNDEFINED(this[i])) {
- throw MakeTypeError("array_functions_on_frozen",
- ["Array.prototype.shift"]);
- }
- }
- }
+ var array = TO_OBJECT_INLINE(this);
+ var len = TO_UINT32(array.length);
+ var num_arguments = %_ArgumentsLength();
+ var is_sealed = ObjectIsSealed(array);
- SimpleMove(this, 0, 0, len, num_arguments);
+ if (IS_ARRAY(array) && !is_sealed) {
+ SmartMove(array, 0, 0, len, num_arguments);
+ } else {
+ SimpleMove(array, 0, 0, len, num_arguments);
}
for (var i = 0; i < num_arguments; i++) {
- this[i] = %_Arguments(i);
+ array[i] = %_Arguments(i);
}
- this.length = len + num_arguments;
-
- return this.length;
+ var new_length = len + num_arguments;
+ array.length = new_length;
+ return new_length;
}
function ArraySlice(start, end) {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice");
- var len = TO_UINT32(this.length);
+ var array = TO_OBJECT_INLINE(this);
+ var len = TO_UINT32(array.length);
var start_i = TO_INTEGER(start);
var end_i = len;
@@ -705,13 +672,13 @@ function ArraySlice(start, end) {
if (end_i < start_i) return result;
- if (IS_ARRAY(this) &&
- !%IsObserved(this) &&
+ if (IS_ARRAY(array) &&
+ !%IsObserved(array) &&
(end_i > 1000) &&
- (%EstimateNumberOfElements(this) < end_i)) {
- SmartSlice(this, start_i, end_i - start_i, len, result);
+ (%EstimateNumberOfElements(array) < end_i)) {
+ SmartSlice(array, start_i, end_i - start_i, len, result);
} else {
- SimpleSlice(this, start_i, end_i - start_i, len, result);
+ SimpleSlice(array, start_i, end_i - start_i, len, result);
}
result.length = end_i - start_i;
@@ -799,7 +766,8 @@ function ArraySplice(start, delete_count) {
return ObservedArraySplice.apply(this, arguments);
var num_arguments = %_ArgumentsLength();
- var len = TO_UINT32(this.length);
+ var array = TO_OBJECT_INLINE(this);
+ var len = TO_UINT32(array.length);
var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len);
var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len,
start_i);
@@ -807,32 +775,32 @@ function ArraySplice(start, delete_count) {
deleted_elements.length = del_count;
var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
- if (del_count != num_elements_to_add && $Object.isSealed(this)) {
+ if (del_count != num_elements_to_add && ObjectIsSealed(array)) {
throw MakeTypeError("array_functions_change_sealed",
["Array.prototype.splice"]);
- } else if (del_count > 0 && $Object.isFrozen(this)) {
+ } else if (del_count > 0 && ObjectIsFrozen(array)) {
throw MakeTypeError("array_functions_on_frozen",
["Array.prototype.splice"]);
}
var use_simple_splice = true;
- if (IS_ARRAY(this) &&
+ if (IS_ARRAY(array) &&
num_elements_to_add !== del_count) {
// If we are only deleting/moving a few things near the end of the
// array then the simple version is going to be faster, because it
// doesn't touch most of the array.
- var estimated_non_hole_elements = %EstimateNumberOfElements(this);
+ var estimated_non_hole_elements = %EstimateNumberOfElements(array);
if (len > 20 && (estimated_non_hole_elements >> 2) < (len - start_i)) {
use_simple_splice = false;
}
}
if (use_simple_splice) {
- SimpleSlice(this, start_i, del_count, len, deleted_elements);
- SimpleMove(this, start_i, del_count, len, num_elements_to_add);
+ SimpleSlice(array, start_i, del_count, len, deleted_elements);
+ SimpleMove(array, start_i, del_count, len, num_elements_to_add);
} else {
- SmartSlice(this, start_i, del_count, len, deleted_elements);
- SmartMove(this, start_i, del_count, len, num_elements_to_add);
+ SmartSlice(array, start_i, del_count, len, deleted_elements);
+ SmartMove(array, start_i, del_count, len, num_elements_to_add);
}
// Insert the arguments into the resulting array in
@@ -841,9 +809,9 @@ function ArraySplice(start, delete_count) {
var arguments_index = 2;
var arguments_length = %_ArgumentsLength();
while (arguments_index < arguments_length) {
- this[i++] = %_Arguments(arguments_index++);
+ array[i++] = %_Arguments(arguments_index++);
}
- this.length = len - del_count + num_elements_to_add;
+ array.length = len - del_count + num_elements_to_add;
// Return the deleted elements.
return deleted_elements;
@@ -1160,28 +1128,16 @@ function ArrayFilter(f, receiver) {
var result = new $Array();
var accumulator = new InternalArray();
var accumulator_length = 0;
- if (%DebugCallbackSupportsStepping(f)) {
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- // Prepare break slots for debugger step in.
- %DebugPrepareStepInIfStepping(f);
- if (%_CallFunction(receiver, element, i, array, f)) {
- accumulator[accumulator_length++] = element;
- }
- }
- }
- } else {
- // This is a duplicate of the previous loop sans debug stepping.
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- if (%_CallFunction(receiver, element, i, array, f)) {
- accumulator[accumulator_length++] = element;
- }
+ var stepping = %_DebugCallbackSupportsStepping(f);
+ for (var i = 0; i < length; i++) {
+ if (i in array) {
+ var element = array[i];
+ // Prepare break slots for debugger step in.
+ if (stepping) %DebugPrepareStepInIfStepping(f);
+ if (%_CallFunction(receiver, element, i, array, f)) {
+ accumulator[accumulator_length++] = element;
}
}
- // End of duplicate.
}
%MoveArrayContents(accumulator, result);
return result;
@@ -1205,24 +1161,14 @@ function ArrayForEach(f, receiver) {
receiver = ToObject(receiver);
}
- if (%DebugCallbackSupportsStepping(f)) {
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- // Prepare break slots for debugger step in.
- %DebugPrepareStepInIfStepping(f);
- %_CallFunction(receiver, element, i, array, f);
- }
+ var stepping = %_DebugCallbackSupportsStepping(f);
+ for (var i = 0; i < length; i++) {
+ if (i in array) {
+ var element = array[i];
+ // Prepare break slots for debugger step in.
+ if (stepping) %DebugPrepareStepInIfStepping(f);
+ %_CallFunction(receiver, element, i, array, f);
}
- } else {
- // This is a duplicate of the previous loop sans debug stepping.
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- %_CallFunction(receiver, element, i, array, f);
- }
- }
- // End of duplicate.
}
}
@@ -1246,24 +1192,14 @@ function ArraySome(f, receiver) {
receiver = ToObject(receiver);
}
- if (%DebugCallbackSupportsStepping(f)) {
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- // Prepare break slots for debugger step in.
- %DebugPrepareStepInIfStepping(f);
- if (%_CallFunction(receiver, element, i, array, f)) return true;
- }
+ var stepping = %_DebugCallbackSupportsStepping(f);
+ for (var i = 0; i < length; i++) {
+ if (i in array) {
+ var element = array[i];
+ // Prepare break slots for debugger step in.
+ if (stepping) %DebugPrepareStepInIfStepping(f);
+ if (%_CallFunction(receiver, element, i, array, f)) return true;
}
- } else {
- // This is a duplicate of the previous loop sans debug stepping.
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- if (%_CallFunction(receiver, element, i, array, f)) return true;
- }
- }
- // End of duplicate.
}
return false;
}
@@ -1286,24 +1222,14 @@ function ArrayEvery(f, receiver) {
receiver = ToObject(receiver);
}
- if (%DebugCallbackSupportsStepping(f)) {
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- // Prepare break slots for debugger step in.
- %DebugPrepareStepInIfStepping(f);
- if (!%_CallFunction(receiver, element, i, array, f)) return false;
- }
- }
- } else {
- // This is a duplicate of the previous loop sans debug stepping.
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- if (!%_CallFunction(receiver, element, i, array, f)) return false;
- }
+ var stepping = %_DebugCallbackSupportsStepping(f);
+ for (var i = 0; i < length; i++) {
+ if (i in array) {
+ var element = array[i];
+ // Prepare break slots for debugger step in.
+ if (stepping) %DebugPrepareStepInIfStepping(f);
+ if (!%_CallFunction(receiver, element, i, array, f)) return false;
}
- // End of duplicate.
}
return true;
}
@@ -1327,24 +1253,14 @@ function ArrayMap(f, receiver) {
var result = new $Array();
var accumulator = new InternalArray(length);
- if (%DebugCallbackSupportsStepping(f)) {
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- // Prepare break slots for debugger step in.
- %DebugPrepareStepInIfStepping(f);
- accumulator[i] = %_CallFunction(receiver, element, i, array, f);
- }
- }
- } else {
- // This is a duplicate of the previous loop sans debug stepping.
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- accumulator[i] = %_CallFunction(receiver, element, i, array, f);
- }
+ var stepping = %_DebugCallbackSupportsStepping(f);
+ for (var i = 0; i < length; i++) {
+ if (i in array) {
+ var element = array[i];
+ // Prepare break slots for debugger step in.
+ if (stepping) %DebugPrepareStepInIfStepping(f);
+ accumulator[i] = %_CallFunction(receiver, element, i, array, f);
}
- // End of duplicate.
}
%MoveArrayContents(accumulator, result);
return result;
@@ -1484,27 +1400,14 @@ function ArrayReduce(callback, current) {
}
var receiver = %GetDefaultReceiver(callback);
-
- if (%DebugCallbackSupportsStepping(callback)) {
- for (; i < length; i++) {
- if (i in array) {
- var element = array[i];
- // Prepare break slots for debugger step in.
- %DebugPrepareStepInIfStepping(callback);
- current =
- %_CallFunction(receiver, current, element, i, array, callback);
- }
+ var stepping = %_DebugCallbackSupportsStepping(callback);
+ for (; i < length; i++) {
+ if (i in array) {
+ var element = array[i];
+ // Prepare break slots for debugger step in.
+ if (stepping) %DebugPrepareStepInIfStepping(callback);
+ current = %_CallFunction(receiver, current, element, i, array, callback);
}
- } else {
- // This is a duplicate of the previous loop sans debug stepping.
- for (; i < length; i++) {
- if (i in array) {
- var element = array[i];
- current =
- %_CallFunction(receiver, current, element, i, array, callback);
- }
- }
- // End of duplicate.
}
return current;
}
@@ -1534,27 +1437,14 @@ function ArrayReduceRight(callback, current) {
}
var receiver = %GetDefaultReceiver(callback);
-
- if (%DebugCallbackSupportsStepping(callback)) {
- for (; i >= 0; i--) {
- if (i in array) {
- var element = array[i];
- // Prepare break slots for debugger step in.
- %DebugPrepareStepInIfStepping(callback);
- current =
- %_CallFunction(receiver, current, element, i, array, callback);
- }
- }
- } else {
- // This is a duplicate of the previous loop sans debug stepping.
- for (; i >= 0; i--) {
- if (i in array) {
- var element = array[i];
- current =
- %_CallFunction(receiver, current, element, i, array, callback);
- }
+ var stepping = %_DebugCallbackSupportsStepping(callback);
+ for (; i >= 0; i--) {
+ if (i in array) {
+ var element = array[i];
+ // Prepare break slots for debugger step in.
+ if (stepping) %DebugPrepareStepInIfStepping(callback);
+ current = %_CallFunction(receiver, current, element, i, array, callback);
}
- // End of duplicate.
}
return current;
}
diff --git a/deps/v8/src/arraybuffer.js b/deps/v8/src/arraybuffer.js
index d5fd9adbad..44989f5dbf 100644
--- a/deps/v8/src/arraybuffer.js
+++ b/deps/v8/src/arraybuffer.js
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
"use strict";
@@ -40,12 +17,12 @@ function ArrayBufferConstructor(length) { // length = 1
}
}
-function ArrayBufferGetByteLength() {
+function ArrayBufferGetByteLen() {
if (!IS_ARRAYBUFFER(this)) {
throw MakeTypeError('incompatible_method_receiver',
['ArrayBuffer.prototype.byteLength', this]);
}
- return %ArrayBufferGetByteLength(this);
+ return %_ArrayBufferGetByteLength(this);
}
// ES6 Draft 15.13.5.5.3
@@ -60,7 +37,7 @@ function ArrayBufferSlice(start, end) {
end = TO_INTEGER(end);
}
var first;
- var byte_length = %ArrayBufferGetByteLength(this);
+ var byte_length = %_ArrayBufferGetByteLength(this);
if (relativeStart < 0) {
first = MathMax(byte_length + relativeStart, 0);
} else {
@@ -99,7 +76,7 @@ function SetUpArrayBuffer() {
// Set up the constructor property on the ArrayBuffer prototype object.
%SetProperty($ArrayBuffer.prototype, "constructor", $ArrayBuffer, DONT_ENUM);
- InstallGetter($ArrayBuffer.prototype, "byteLength", ArrayBufferGetByteLength);
+ InstallGetter($ArrayBuffer.prototype, "byteLength", ArrayBufferGetByteLen);
InstallFunctions($ArrayBuffer, DONT_ENUM, $Array(
"isView", ArrayBufferIsView
diff --git a/deps/v8/src/assembler.cc b/deps/v8/src/assembler.cc
index 772b6d6963..38604538b5 100644
--- a/deps/v8/src/assembler.cc
+++ b/deps/v8/src/assembler.cc
@@ -39,6 +39,7 @@
#include "builtins.h"
#include "counters.h"
#include "cpu.h"
+#include "cpu-profiler.h"
#include "debug.h"
#include "deoptimizer.h"
#include "execution.h"
@@ -190,7 +191,7 @@ PredictableCodeSizeScope::~PredictableCodeSizeScope() {
#ifdef DEBUG
CpuFeatureScope::CpuFeatureScope(AssemblerBase* assembler, CpuFeature f)
: assembler_(assembler) {
- ASSERT(CpuFeatures::IsSafeForSnapshot(f));
+ ASSERT(CpuFeatures::IsSafeForSnapshot(assembler_->isolate(), f));
old_enabled_ = assembler_->enabled_cpu_features();
uint64_t mask = static_cast<uint64_t>(1) << f;
// TODO(svenpanne) This special case below doesn't belong here!
@@ -213,13 +214,14 @@ CpuFeatureScope::~CpuFeatureScope() {
// -----------------------------------------------------------------------------
// Implementation of PlatformFeatureScope
-PlatformFeatureScope::PlatformFeatureScope(CpuFeature f)
- : old_cross_compile_(CpuFeatures::cross_compile_) {
+PlatformFeatureScope::PlatformFeatureScope(Isolate* isolate, CpuFeature f)
+ : isolate_(isolate), old_cross_compile_(CpuFeatures::cross_compile_) {
// CpuFeatures is a global singleton, therefore this is only safe in
// single threaded code.
- ASSERT(Serializer::enabled());
+ ASSERT(Serializer::enabled(isolate));
uint64_t mask = static_cast<uint64_t>(1) << f;
CpuFeatures::cross_compile_ |= mask;
+ USE(isolate_);
}
@@ -722,7 +724,10 @@ RelocIterator::RelocIterator(Code* code, int mode_mask) {
last_id_ = 0;
last_position_ = 0;
byte* sequence = code->FindCodeAgeSequence();
- if (sequence != NULL && !Code::IsYoungSequence(sequence)) {
+ // We get the isolate from the map, because at serialization time
+ // the code pointer has been cloned and isn't really in heap space.
+ Isolate* isolate = code->map()->GetIsolate();
+ if (sequence != NULL && !Code::IsYoungSequence(isolate, sequence)) {
code_age_sequence_ = sequence;
} else {
code_age_sequence_ = NULL;
@@ -779,9 +784,6 @@ const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
case RelocInfo::CONSTRUCT_CALL:
return "code target (js construct call)";
case RelocInfo::DEBUG_BREAK:
-#ifndef ENABLE_DEBUGGER_SUPPORT
- UNREACHABLE();
-#endif
return "debug break";
case RelocInfo::CODE_TARGET:
return "code target";
@@ -808,9 +810,6 @@ const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
case RelocInfo::VENEER_POOL:
return "veneer pool";
case RelocInfo::DEBUG_BREAK_SLOT:
-#ifndef ENABLE_DEBUGGER_SUPPORT
- UNREACHABLE();
-#endif
return "debug break slot";
case RelocInfo::CODE_AGE_SEQUENCE:
return "code_age_sequence";
@@ -860,7 +859,7 @@ void RelocInfo::Print(Isolate* isolate, FILE* out) {
#ifdef VERIFY_HEAP
-void RelocInfo::Verify() {
+void RelocInfo::Verify(Isolate* isolate) {
switch (rmode_) {
case EMBEDDED_OBJECT:
Object::VerifyPointer(target_object());
@@ -869,10 +868,6 @@ void RelocInfo::Verify() {
Object::VerifyPointer(target_cell());
break;
case DEBUG_BREAK:
-#ifndef ENABLE_DEBUGGER_SUPPORT
- UNREACHABLE();
- break;
-#endif
case CONSTRUCT_CALL:
case CODE_TARGET_WITH_ID:
case CODE_TARGET: {
@@ -881,7 +876,7 @@ void RelocInfo::Verify() {
CHECK(addr != NULL);
// Check that we can find the right code object.
Code* code = Code::GetCodeFromTargetAddress(addr);
- Object* found = code->GetIsolate()->FindCodeObject(addr);
+ Object* found = isolate->FindCodeObject(addr);
CHECK(found->IsCode());
CHECK(code->address() == HeapObject::cast(found)->address());
break;
@@ -903,7 +898,7 @@ void RelocInfo::Verify() {
UNREACHABLE();
break;
case CODE_AGE_SEQUENCE:
- ASSERT(Code::IsYoungSequence(pc_) || code_age_stub()->IsCode());
+ ASSERT(Code::IsYoungSequence(isolate, pc_) || code_age_stub()->IsCode());
break;
}
}
@@ -1014,11 +1009,9 @@ ExternalReference::ExternalReference(const IC_Utility& ic_utility,
Isolate* isolate)
: address_(Redirect(isolate, ic_utility.address())) {}
-#ifdef ENABLE_DEBUGGER_SUPPORT
ExternalReference::ExternalReference(const Debug_Address& debug_address,
Isolate* isolate)
: address_(debug_address.address(isolate)) {}
-#endif
ExternalReference::ExternalReference(StatsCounter* counter)
: address_(reinterpret_cast<Address>(counter->GetInternalPointer())) {}
@@ -1053,18 +1046,6 @@ ExternalReference ExternalReference::flush_icache_function(Isolate* isolate) {
}
-ExternalReference ExternalReference::perform_gc_function(Isolate* isolate) {
- return
- ExternalReference(Redirect(isolate, FUNCTION_ADDR(Runtime::PerformGC)));
-}
-
-
-ExternalReference ExternalReference::out_of_memory_function(Isolate* isolate) {
- return
- ExternalReference(Redirect(isolate, FUNCTION_ADDR(Runtime::OutOfMemory)));
-}
-
-
ExternalReference ExternalReference::delete_handle_scope_extensions(
Isolate* isolate) {
return ExternalReference(Redirect(
@@ -1340,6 +1321,30 @@ ExternalReference ExternalReference::address_of_uint32_bias() {
}
+ExternalReference ExternalReference::is_profiling_address(Isolate* isolate) {
+ return ExternalReference(isolate->cpu_profiler()->is_profiling_address());
+}
+
+
+ExternalReference ExternalReference::invoke_function_callback(
+ Isolate* isolate) {
+ Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
+ ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
+ ApiFunction thunk_fun(thunk_address);
+ return ExternalReference(&thunk_fun, thunk_type, isolate);
+}
+
+
+ExternalReference ExternalReference::invoke_accessor_getter_callback(
+ Isolate* isolate) {
+ Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+ ExternalReference::Type thunk_type =
+ ExternalReference::PROFILING_GETTER_CALL;
+ ApiFunction thunk_fun(thunk_address);
+ return ExternalReference(&thunk_fun, thunk_type, isolate);
+}
+
+
#ifndef V8_INTERPRETED_REGEXP
ExternalReference ExternalReference::re_check_stack_guard_state(
@@ -1538,7 +1543,6 @@ ExternalReference ExternalReference::mod_two_doubles_operation(
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
ExternalReference ExternalReference::debug_break(Isolate* isolate) {
return ExternalReference(Redirect(isolate, FUNCTION_ADDR(Debug_Break)));
}
@@ -1548,7 +1552,6 @@ ExternalReference ExternalReference::debug_step_in_fp_address(
Isolate* isolate) {
return ExternalReference(isolate->debug()->step_in_fp_addr());
}
-#endif
void PositionsRecorder::RecordPosition(int pos) {
diff --git a/deps/v8/src/assembler.h b/deps/v8/src/assembler.h
index 0349b06582..c67253c489 100644
--- a/deps/v8/src/assembler.h
+++ b/deps/v8/src/assembler.h
@@ -107,6 +107,22 @@ class AssemblerBase: public Malloced {
};
+// Avoids emitting debug code during the lifetime of this scope object.
+class DontEmitDebugCodeScope BASE_EMBEDDED {
+ public:
+ explicit DontEmitDebugCodeScope(AssemblerBase* assembler)
+ : assembler_(assembler), old_value_(assembler->emit_debug_code()) {
+ assembler_->set_emit_debug_code(false);
+ }
+ ~DontEmitDebugCodeScope() {
+ assembler_->set_emit_debug_code(old_value_);
+ };
+ private:
+ AssemblerBase* assembler_;
+ bool old_value_;
+};
+
+
// Avoids using instructions that vary in size in unpredictable ways between the
// snapshot and the running VM.
class PredictableCodeSizeScope {
@@ -142,10 +158,11 @@ class CpuFeatureScope BASE_EMBEDDED {
// different CPU.
class PlatformFeatureScope BASE_EMBEDDED {
public:
- explicit PlatformFeatureScope(CpuFeature f);
+ PlatformFeatureScope(Isolate* isolate, CpuFeature f);
~PlatformFeatureScope();
private:
+ Isolate* isolate_;
uint64_t old_cross_compile_;
};
@@ -237,7 +254,7 @@ enum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs };
// describe a property of the datum. Such rmodes are useful for GC
// and nice disassembly output.
-class RelocInfo BASE_EMBEDDED {
+class RelocInfo {
public:
// The constant kNoPosition is used with the collecting of source positions
// in the relocation information. Two types of source positions are collected
@@ -503,7 +520,7 @@ class RelocInfo BASE_EMBEDDED {
void Print(Isolate* isolate, FILE* out);
#endif // ENABLE_DISASSEMBLER
#ifdef VERIFY_HEAP
- void Verify();
+ void Verify(Isolate* isolate);
#endif
static const int kCodeTargetMask = (1 << (LAST_CODE_ENUM + 1)) - 1;
@@ -653,9 +670,7 @@ class RelocIterator: public Malloced {
//----------------------------------------------------------------------------
class IC_Utility;
class SCTableReference;
-#ifdef ENABLE_DEBUGGER_SUPPORT
class Debug_Address;
-#endif
// An ExternalReference represents a C++ address used in the generated
@@ -668,7 +683,7 @@ class ExternalReference BASE_EMBEDDED {
// Used in the simulator to support different native api calls.
enum Type {
// Builtin call.
- // MaybeObject* f(v8::internal::Arguments).
+ // Object* f(v8::internal::Arguments).
BUILTIN_CALL, // default
// Builtin that takes float arguments and returns an int.
@@ -725,9 +740,7 @@ class ExternalReference BASE_EMBEDDED {
ExternalReference(const IC_Utility& ic_utility, Isolate* isolate);
-#ifdef ENABLE_DEBUGGER_SUPPORT
ExternalReference(const Debug_Address& debug_address, Isolate* isolate);
-#endif
explicit ExternalReference(StatsCounter* counter);
@@ -747,8 +760,6 @@ class ExternalReference BASE_EMBEDDED {
static ExternalReference store_buffer_overflow_function(
Isolate* isolate);
static ExternalReference flush_icache_function(Isolate* isolate);
- static ExternalReference perform_gc_function(Isolate* isolate);
- static ExternalReference out_of_memory_function(Isolate* isolate);
static ExternalReference delete_handle_scope_extensions(Isolate* isolate);
static ExternalReference get_date_field_function(Isolate* isolate);
@@ -850,15 +861,17 @@ class ExternalReference BASE_EMBEDDED {
static ExternalReference cpu_features();
+ static ExternalReference is_profiling_address(Isolate* isolate);
+ static ExternalReference invoke_function_callback(Isolate* isolate);
+ static ExternalReference invoke_accessor_getter_callback(Isolate* isolate);
+
Address address() const { return reinterpret_cast<Address>(address_); }
-#ifdef ENABLE_DEBUGGER_SUPPORT
// Function Debug::Break()
static ExternalReference debug_break(Isolate* isolate);
// Used to check if single stepping is enabled in generated code.
static ExternalReference debug_step_in_fp_address(Isolate* isolate);
-#endif
#ifndef V8_INTERPRETED_REGEXP
// C functions called from RegExp generated code.
diff --git a/deps/v8/src/assert-scope.h b/deps/v8/src/assert-scope.h
index 428e6d007e..5086eaa426 100644
--- a/deps/v8/src/assert-scope.h
+++ b/deps/v8/src/assert-scope.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ASSERT_SCOPE_H_
#define V8_ASSERT_SCOPE_H_
@@ -50,7 +27,8 @@ enum PerThreadAssertType {
enum PerIsolateAssertType {
JAVASCRIPT_EXECUTION_ASSERT,
JAVASCRIPT_EXECUTION_THROWS,
- ALLOCATION_FAILURE_ASSERT
+ ALLOCATION_FAILURE_ASSERT,
+ DEOPTIMIZATION_ASSERT
};
@@ -268,6 +246,14 @@ typedef PerIsolateAssertScopeDebugOnly<ALLOCATION_FAILURE_ASSERT, false>
typedef PerIsolateAssertScopeDebugOnly<ALLOCATION_FAILURE_ASSERT, true>
AllowAllocationFailure;
+// Scope to document where we do not expect deoptimization.
+typedef PerIsolateAssertScopeDebugOnly<DEOPTIMIZATION_ASSERT, false>
+ DisallowDeoptimization;
+
+// Scope to introduce an exception to DisallowDeoptimization.
+typedef PerIsolateAssertScopeDebugOnly<DEOPTIMIZATION_ASSERT, true>
+ AllowDeoptimization;
+
} } // namespace v8::internal
#endif // V8_ASSERT_SCOPE_H_
diff --git a/deps/v8/src/ast.cc b/deps/v8/src/ast.cc
index f6cf18915b..303c442f84 100644
--- a/deps/v8/src/ast.cc
+++ b/deps/v8/src/ast.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "ast.h"
@@ -56,29 +33,30 @@ AST_NODE_LIST(DECL_ACCEPT)
// Implementation of other node functionality.
-bool Expression::IsSmiLiteral() {
+bool Expression::IsSmiLiteral() const {
return AsLiteral() != NULL && AsLiteral()->value()->IsSmi();
}
-bool Expression::IsStringLiteral() {
+bool Expression::IsStringLiteral() const {
return AsLiteral() != NULL && AsLiteral()->value()->IsString();
}
-bool Expression::IsNullLiteral() {
+bool Expression::IsNullLiteral() const {
return AsLiteral() != NULL && AsLiteral()->value()->IsNull();
}
-bool Expression::IsUndefinedLiteral(Isolate* isolate) {
- VariableProxy* var_proxy = AsVariableProxy();
+bool Expression::IsUndefinedLiteral(Isolate* isolate) const {
+ const VariableProxy* var_proxy = AsVariableProxy();
if (var_proxy == NULL) return false;
Variable* var = var_proxy->var();
// The global identifier "undefined" is immutable. Everything
// else could be reassigned.
return var != NULL && var->location() == Variable::UNALLOCATED &&
- var_proxy->name()->Equals(isolate->heap()->undefined_string());
+ String::Equals(var_proxy->name(),
+ isolate->factory()->undefined_string());
}
@@ -207,9 +185,10 @@ ObjectLiteralProperty::ObjectLiteralProperty(
emit_store_ = true;
key_ = key;
value_ = value;
- Object* k = *key->value();
+ Handle<Object> k = key->value();
if (k->IsInternalizedString() &&
- zone->isolate()->heap()->proto_string()->Equals(String::cast(k))) {
+ String::Equals(Handle<String>::cast(k),
+ zone->isolate()->factory()->proto_string())) {
kind_ = PROTOTYPE;
} else if (value_->AsMaterializedLiteral() != NULL) {
kind_ = MATERIALIZED_LITERAL;
@@ -378,9 +357,9 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
} else if (boilerplate_value->IsUninitialized()) {
is_simple = false;
JSObject::SetOwnElement(
- array, i, handle(Smi::FromInt(0), isolate), SLOPPY);
+ array, i, handle(Smi::FromInt(0), isolate), SLOPPY).Assert();
} else {
- JSObject::SetOwnElement(array, i, boilerplate_value, SLOPPY);
+ JSObject::SetOwnElement(array, i, boilerplate_value, SLOPPY).Assert();
}
}
@@ -463,7 +442,7 @@ void BinaryOperation::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
}
-bool BinaryOperation::ResultOverwriteAllowed() {
+bool BinaryOperation::ResultOverwriteAllowed() const {
switch (op_) {
case Token::COMMA:
case Token::OR:
@@ -592,14 +571,9 @@ void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
}
-int Call::ComputeFeedbackSlotCount(Isolate* isolate) {
+bool Call::IsUsingCallFeedbackSlot(Isolate* isolate) const {
CallType call_type = GetCallType(isolate);
- if (call_type == LOOKUP_SLOT_CALL || call_type == OTHER_CALL) {
- // Call only uses a slot in some cases.
- return 1;
- }
-
- return 0;
+ return (call_type != POSSIBLY_EVAL_CALL);
}
@@ -1177,7 +1151,7 @@ Handle<String> Literal::ToString() {
} else {
str = DoubleToCString(value_->Number(), buffer);
}
- return isolate_->factory()->NewStringFromAscii(CStrVector(str));
+ return isolate_->factory()->NewStringFromAsciiChecked(str);
}
diff --git a/deps/v8/src/ast.h b/deps/v8/src/ast.h
index c6ee71ed83..0115d98827 100644
--- a/deps/v8/src/ast.h
+++ b/deps/v8/src/ast.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_AST_H_
#define V8_AST_H_
@@ -182,15 +159,21 @@ class AstProperties V8_FINAL BASE_EMBEDDED {
public:
class Flags : public EnumSet<AstPropertiesFlag, int> {};
- AstProperties() : node_count_(0) {}
+AstProperties() : node_count_(0), feedback_slots_(0) {}
Flags* flags() { return &flags_; }
int node_count() { return node_count_; }
void add_node_count(int count) { node_count_ += count; }
+ int feedback_slots() const { return feedback_slots_; }
+ void increase_feedback_slots(int count) {
+ feedback_slots_ += count;
+ }
+
private:
Flags flags_;
int node_count_;
+ int feedback_slots_;
};
@@ -215,9 +198,14 @@ class AstNode: public ZoneObject {
int position() const { return position_; }
// Type testing & conversion functions overridden by concrete subclasses.
-#define DECLARE_NODE_FUNCTIONS(type) \
- bool Is##type() { return node_type() == AstNode::k##type; } \
- type* As##type() { return Is##type() ? reinterpret_cast<type*>(this) : NULL; }
+#define DECLARE_NODE_FUNCTIONS(type) \
+ bool Is##type() const { return node_type() == AstNode::k##type; } \
+ type* As##type() { \
+ return Is##type() ? reinterpret_cast<type*>(this) : NULL; \
+ } \
+ const type* As##type() const { \
+ return Is##type() ? reinterpret_cast<const type*>(this) : NULL; \
+ }
AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
#undef DECLARE_NODE_FUNCTIONS
@@ -276,8 +264,7 @@ class SmallMapList V8_FINAL {
int length() const { return list_.length(); }
void AddMapIfMissing(Handle<Map> map, Zone* zone) {
- map = Map::CurrentMapForDeprecated(map);
- if (map.is_null()) return;
+ if (!Map::CurrentMapForDeprecated(map).ToHandle(&map)) return;
for (int i = 0; i < length(); ++i) {
if (at(i).is_identical_to(map)) return;
}
@@ -325,35 +312,35 @@ class Expression : public AstNode {
kTest
};
- virtual bool IsValidLeftHandSide() { return false; }
+ virtual bool IsValidReferenceExpression() const { return false; }
// Helpers for ToBoolean conversion.
- virtual bool ToBooleanIsTrue() { return false; }
- virtual bool ToBooleanIsFalse() { return false; }
+ virtual bool ToBooleanIsTrue() const { return false; }
+ virtual bool ToBooleanIsFalse() const { return false; }
// Symbols that cannot be parsed as array indices are considered property
// names. We do not treat symbols that can be array indexes as property
// names because [] for string objects is handled only by keyed ICs.
- virtual bool IsPropertyName() { return false; }
+ virtual bool IsPropertyName() const { return false; }
// True iff the result can be safely overwritten (to avoid allocation).
// False for operations that can return one of their operands.
- virtual bool ResultOverwriteAllowed() { return false; }
+ virtual bool ResultOverwriteAllowed() const { return false; }
// True iff the expression is a literal represented as a smi.
- bool IsSmiLiteral();
+ bool IsSmiLiteral() const;
// True iff the expression is a string literal.
- bool IsStringLiteral();
+ bool IsStringLiteral() const;
// True iff the expression is the null literal.
- bool IsNullLiteral();
+ bool IsNullLiteral() const;
// True if we can prove that the expression is the undefined literal.
- bool IsUndefinedLiteral(Isolate* isolate);
+ bool IsUndefinedLiteral(Isolate* isolate) const;
// Expression type bounds
- Bounds bounds() { return bounds_; }
+ Bounds bounds() const { return bounds_; }
void set_bounds(Bounds bounds) { bounds_ = bounds; }
// Type feedback information for assignments and properties.
@@ -925,8 +912,7 @@ class ForInStatement V8_FINAL : public ForEachStatement,
}
// Type feedback information.
- virtual ComputablePhase GetComputablePhase() { return DURING_PARSE; }
- virtual int ComputeFeedbackSlotCount(Isolate* isolate) { return 1; }
+ virtual int ComputeFeedbackSlotCount() { return 1; }
virtual void SetFirstFeedbackSlot(int slot) { for_in_feedback_slot_ = slot; }
int ForInFeedbackSlot() {
@@ -1346,7 +1332,7 @@ class Literal V8_FINAL : public Expression {
public:
DECLARE_NODE_TYPE(Literal)
- virtual bool IsPropertyName() V8_OVERRIDE {
+ virtual bool IsPropertyName() const V8_OVERRIDE {
if (value_->IsInternalizedString()) {
uint32_t ignored;
return !String::cast(*value_)->AsArrayIndex(&ignored);
@@ -1359,10 +1345,10 @@ class Literal V8_FINAL : public Expression {
return Handle<String>::cast(value_);
}
- virtual bool ToBooleanIsTrue() V8_OVERRIDE {
+ virtual bool ToBooleanIsTrue() const V8_OVERRIDE {
return value_->BooleanValue();
}
- virtual bool ToBooleanIsFalse() V8_OVERRIDE {
+ virtual bool ToBooleanIsFalse() const V8_OVERRIDE {
return !value_->BooleanValue();
}
@@ -1389,7 +1375,7 @@ class Literal V8_FINAL : public Expression {
static bool Match(void* literal1, void* literal2) {
Handle<String> s1 = static_cast<Literal*>(literal1)->ToString();
Handle<String> s2 = static_cast<Literal*>(literal2)->ToString();
- return s1->Equals(*s2);
+ return String::Equals(s1, s2);
}
TypeFeedbackId LiteralFeedbackId() const { return reuse(id()); }
@@ -1637,19 +1623,17 @@ class VariableProxy V8_FINAL : public Expression {
public:
DECLARE_NODE_TYPE(VariableProxy)
- virtual bool IsValidLeftHandSide() V8_OVERRIDE {
- return var_ == NULL ? true : var_->IsValidLeftHandSide();
+ virtual bool IsValidReferenceExpression() const V8_OVERRIDE {
+ return var_ == NULL ? true : var_->IsValidReference();
}
- bool IsVariable(Handle<String> n) {
+ bool IsVariable(Handle<String> n) const {
return !is_this() && name().is_identical_to(n);
}
- bool IsArguments() { return var_ != NULL && var_->is_arguments(); }
+ bool IsArguments() const { return var_ != NULL && var_->is_arguments(); }
- bool IsLValue() {
- return is_lvalue_;
- }
+ bool IsLValue() const { return is_lvalue_; }
Handle<String> name() const { return name_; }
Variable* var() const { return var_; }
@@ -1687,7 +1671,7 @@ class Property V8_FINAL : public Expression {
public:
DECLARE_NODE_TYPE(Property)
- virtual bool IsValidLeftHandSide() V8_OVERRIDE { return true; }
+ virtual bool IsValidReferenceExpression() const V8_OVERRIDE { return true; }
Expression* obj() const { return obj_; }
Expression* key() const { return key_; }
@@ -1754,8 +1738,7 @@ class Call V8_FINAL : public Expression, public FeedbackSlotInterface {
ZoneList<Expression*>* arguments() const { return arguments_; }
// Type feedback information.
- virtual ComputablePhase GetComputablePhase() { return AFTER_SCOPING; }
- virtual int ComputeFeedbackSlotCount(Isolate* isolate);
+ virtual int ComputeFeedbackSlotCount() { return 1; }
virtual void SetFirstFeedbackSlot(int slot) {
call_feedback_slot_ = slot;
}
@@ -1798,6 +1781,7 @@ class Call V8_FINAL : public Expression, public FeedbackSlotInterface {
// Helpers to determine how to handle the call.
CallType GetCallType(Isolate* isolate) const;
+ bool IsUsingCallFeedbackSlot(Isolate* isolate) const;
#ifdef DEBUG
// Used to assert that the FullCodeGenerator records the return site.
@@ -1839,8 +1823,7 @@ class CallNew V8_FINAL : public Expression, public FeedbackSlotInterface {
ZoneList<Expression*>* arguments() const { return arguments_; }
// Type feedback information.
- virtual ComputablePhase GetComputablePhase() { return DURING_PARSE; }
- virtual int ComputeFeedbackSlotCount(Isolate* isolate) {
+ virtual int ComputeFeedbackSlotCount() {
return FLAG_pretenuring_call_new ? 2 : 1;
}
virtual void SetFirstFeedbackSlot(int slot) {
@@ -1970,7 +1953,7 @@ class BinaryOperation V8_FINAL : public Expression {
public:
DECLARE_NODE_TYPE(BinaryOperation)
- virtual bool ResultOverwriteAllowed();
+ virtual bool ResultOverwriteAllowed() const V8_OVERRIDE;
Token::Value op() const { return op_; }
Expression* left() const { return left_; }
@@ -2376,14 +2359,8 @@ class FunctionLiteral V8_FINAL : public Expression {
void set_ast_properties(AstProperties* ast_properties) {
ast_properties_ = *ast_properties;
}
- void set_slot_processor(DeferredFeedbackSlotProcessor* slot_processor) {
- slot_processor_ = *slot_processor;
- }
- void ProcessFeedbackSlots(Isolate* isolate) {
- slot_processor_.ProcessFeedbackSlots(isolate);
- }
int slot_count() {
- return slot_processor_.slot_count();
+ return ast_properties_.feedback_slots();
}
bool dont_optimize() { return dont_optimize_reason_ != kNoReason; }
BailoutReason dont_optimize_reason() { return dont_optimize_reason_; }
@@ -2434,7 +2411,6 @@ class FunctionLiteral V8_FINAL : public Expression {
ZoneList<Statement*>* body_;
Handle<String> inferred_name_;
AstProperties ast_properties_;
- DeferredFeedbackSlotProcessor slot_processor_;
BailoutReason dont_optimize_reason_;
int materialized_literal_count_;
@@ -2909,13 +2885,10 @@ private: \
class AstConstructionVisitor BASE_EMBEDDED {
public:
- explicit AstConstructionVisitor(Zone* zone)
- : dont_optimize_reason_(kNoReason),
- zone_(zone) { }
+ AstConstructionVisitor() : dont_optimize_reason_(kNoReason) { }
AstProperties* ast_properties() { return &properties_; }
BailoutReason dont_optimize_reason() { return dont_optimize_reason_; }
- DeferredFeedbackSlotProcessor* slot_processor() { return &slot_processor_; }
private:
template<class> friend class AstNodeFactory;
@@ -2933,20 +2906,20 @@ class AstConstructionVisitor BASE_EMBEDDED {
}
void add_slot_node(FeedbackSlotInterface* slot_node) {
- slot_processor_.add_slot_node(zone_, slot_node);
+ int count = slot_node->ComputeFeedbackSlotCount();
+ if (count > 0) {
+ slot_node->SetFirstFeedbackSlot(properties_.feedback_slots());
+ properties_.increase_feedback_slots(count);
+ }
}
AstProperties properties_;
- DeferredFeedbackSlotProcessor slot_processor_;
BailoutReason dont_optimize_reason_;
- Zone* zone_;
};
class AstNullVisitor BASE_EMBEDDED {
public:
- explicit AstNullVisitor(Zone* zone) {}
-
// Node visitors.
#define DEF_VISIT(type) \
void Visit##type(type* node) {}
@@ -2962,9 +2935,7 @@ class AstNullVisitor BASE_EMBEDDED {
template<class Visitor>
class AstNodeFactory V8_FINAL BASE_EMBEDDED {
public:
- explicit AstNodeFactory(Zone* zone)
- : zone_(zone),
- visitor_(zone) { }
+ explicit AstNodeFactory(Zone* zone) : zone_(zone) { }
Visitor* visitor() { return &visitor_; }
diff --git a/deps/v8/src/atomicops.h b/deps/v8/src/atomicops.h
index 08be2a7d37..9289d171b8 100644
--- a/deps/v8/src/atomicops.h
+++ b/deps/v8/src/atomicops.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// The routines exported by this module are subtle. If you use them, even if
// you get the code right, it will depend on careful reasoning about atomicity
@@ -63,6 +40,7 @@
namespace v8 {
namespace internal {
+typedef char Atomic8;
typedef int32_t Atomic32;
#ifdef V8_HOST_ARCH_64_BIT
// We need to be able to go between Atomic64 and AtomicWord implicitly. This
@@ -120,10 +98,12 @@ Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 new_value);
void MemoryBarrier();
+void NoBarrier_Store(volatile Atomic8* ptr, Atomic8 value);
void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value);
void Acquire_Store(volatile Atomic32* ptr, Atomic32 value);
void Release_Store(volatile Atomic32* ptr, Atomic32 value);
+Atomic8 NoBarrier_Load(volatile const Atomic8* ptr);
Atomic32 NoBarrier_Load(volatile const Atomic32* ptr);
Atomic32 Acquire_Load(volatile const Atomic32* ptr);
Atomic32 Release_Load(volatile const Atomic32* ptr);
diff --git a/deps/v8/src/atomicops_internals_arm64_gcc.h b/deps/v8/src/atomicops_internals_arm64_gcc.h
index e6cac19932..36e30a90c1 100644
--- a/deps/v8/src/atomicops_internals_arm64_gcc.h
+++ b/deps/v8/src/atomicops_internals_arm64_gcc.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file is an internal atomic implementation, use atomicops.h instead.
@@ -34,12 +11,16 @@ namespace v8 {
namespace internal {
inline void MemoryBarrier() {
- __asm__ __volatile__ ( // NOLINT
- "dmb ish \n\t" // Data memory barrier.
- ::: "memory"
- ); // NOLINT
+ __asm__ __volatile__ ("dmb ish" ::: "memory"); // NOLINT
}
+// NoBarrier versions of the operation include "memory" in the clobber list.
+// This is not required for direct usage of the NoBarrier versions of the
+// operations. However this is required for correctness when they are used as
+// part of the Acquire or Release versions, to ensure that nothing from outside
+// the call is reordered between the operation and the memory barrier. This does
+// not change the code generated, so has no or minimal impact on the
+// NoBarrier operations.
inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
@@ -55,13 +36,12 @@ inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
"stxr %w[temp], %w[new_value], %[ptr] \n\t" // Try to store the new value.
"cbnz %w[temp], 0b \n\t" // Retry if it did not work.
"1: \n\t"
- "clrex \n\t" // In case we didn't swap.
: [prev]"=&r" (prev),
[temp]"=&r" (temp),
[ptr]"+Q" (*ptr)
- : [old_value]"r" (old_value),
+ : [old_value]"IJr" (old_value),
[new_value]"r" (new_value)
- : "memory", "cc"
+ : "cc", "memory"
); // NOLINT
return prev;
@@ -101,7 +81,7 @@ inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
: [result]"=&r" (result),
[temp]"=&r" (temp),
[ptr]"+Q" (*ptr)
- : [increment]"r" (increment)
+ : [increment]"IJr" (increment)
: "memory"
); // NOLINT
@@ -110,8 +90,10 @@ inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment) {
+ Atomic32 result;
+
MemoryBarrier();
- Atomic32 result = NoBarrier_AtomicIncrement(ptr, increment);
+ result = NoBarrier_AtomicIncrement(ptr, increment);
MemoryBarrier();
return result;
@@ -121,27 +103,9 @@ inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
Atomic32 prev;
- int32_t temp;
- __asm__ __volatile__ ( // NOLINT
- "0: \n\t"
- "ldxr %w[prev], %[ptr] \n\t" // Load the previous value.
- "cmp %w[prev], %w[old_value] \n\t"
- "bne 1f \n\t"
- "stxr %w[temp], %w[new_value], %[ptr] \n\t" // Try to store the new value.
- "cbnz %w[temp], 0b \n\t" // Retry if it did not work.
- "dmb ish \n\t" // Data memory barrier.
- "1: \n\t"
- // If the compare failed the 'dmb' is unnecessary, but we still need a
- // 'clrex'.
- "clrex \n\t"
- : [prev]"=&r" (prev),
- [temp]"=&r" (temp),
- [ptr]"+Q" (*ptr)
- : [old_value]"r" (old_value),
- [new_value]"r" (new_value)
- : "memory", "cc"
- ); // NOLINT
+ prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ MemoryBarrier();
return prev;
}
@@ -150,31 +114,17 @@ inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
Atomic32 prev;
- int32_t temp;
MemoryBarrier();
-
- __asm__ __volatile__ ( // NOLINT
- "0: \n\t"
- "ldxr %w[prev], %[ptr] \n\t" // Load the previous value.
- "cmp %w[prev], %w[old_value] \n\t"
- "bne 1f \n\t"
- "stxr %w[temp], %w[new_value], %[ptr] \n\t" // Try to store the new value.
- "cbnz %w[temp], 0b \n\t" // Retry if it did not work.
- "1: \n\t"
- // If the compare failed the we still need a 'clrex'.
- "clrex \n\t"
- : [prev]"=&r" (prev),
- [temp]"=&r" (temp),
- [ptr]"+Q" (*ptr)
- : [old_value]"r" (old_value),
- [new_value]"r" (new_value)
- : "memory", "cc"
- ); // NOLINT
+ prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
return prev;
}
+inline void NoBarrier_Store(volatile Atomic8* ptr, Atomic8 value) {
+ *ptr = value;
+}
+
inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
}
@@ -185,8 +135,16 @@ inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
}
inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
- MemoryBarrier();
- *ptr = value;
+ __asm__ __volatile__ ( // NOLINT
+ "stlr %w[value], %[ptr] \n\t"
+ : [ptr]"=Q" (*ptr)
+ : [value]"r" (value)
+ : "memory"
+ ); // NOLINT
+}
+
+inline Atomic8 NoBarrier_Load(volatile const Atomic8* ptr) {
+ return *ptr;
}
inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
@@ -194,8 +152,15 @@ inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
}
inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
- Atomic32 value = *ptr;
- MemoryBarrier();
+ Atomic32 value;
+
+ __asm__ __volatile__ ( // NOLINT
+ "ldar %w[value], %[ptr] \n\t"
+ : [value]"=r" (value)
+ : [ptr]"Q" (*ptr)
+ : "memory"
+ ); // NOLINT
+
return value;
}
@@ -221,13 +186,12 @@ inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
"stxr %w[temp], %[new_value], %[ptr] \n\t"
"cbnz %w[temp], 0b \n\t"
"1: \n\t"
- "clrex \n\t"
: [prev]"=&r" (prev),
[temp]"=&r" (temp),
[ptr]"+Q" (*ptr)
- : [old_value]"r" (old_value),
+ : [old_value]"IJr" (old_value),
[new_value]"r" (new_value)
- : "memory", "cc"
+ : "cc", "memory"
); // NOLINT
return prev;
@@ -267,7 +231,7 @@ inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
: [result]"=&r" (result),
[temp]"=&r" (temp),
[ptr]"+Q" (*ptr)
- : [increment]"r" (increment)
+ : [increment]"IJr" (increment)
: "memory"
); // NOLINT
@@ -276,8 +240,10 @@ inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
Atomic64 increment) {
+ Atomic64 result;
+
MemoryBarrier();
- Atomic64 result = NoBarrier_AtomicIncrement(ptr, increment);
+ result = NoBarrier_AtomicIncrement(ptr, increment);
MemoryBarrier();
return result;
@@ -287,25 +253,9 @@ inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
Atomic64 prev;
- int32_t temp;
- __asm__ __volatile__ ( // NOLINT
- "0: \n\t"
- "ldxr %[prev], %[ptr] \n\t"
- "cmp %[prev], %[old_value] \n\t"
- "bne 1f \n\t"
- "stxr %w[temp], %[new_value], %[ptr] \n\t"
- "cbnz %w[temp], 0b \n\t"
- "dmb ish \n\t"
- "1: \n\t"
- "clrex \n\t"
- : [prev]"=&r" (prev),
- [temp]"=&r" (temp),
- [ptr]"+Q" (*ptr)
- : [old_value]"r" (old_value),
- [new_value]"r" (new_value)
- : "memory", "cc"
- ); // NOLINT
+ prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ MemoryBarrier();
return prev;
}
@@ -314,26 +264,9 @@ inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
Atomic64 prev;
- int32_t temp;
MemoryBarrier();
-
- __asm__ __volatile__ ( // NOLINT
- "0: \n\t"
- "ldxr %[prev], %[ptr] \n\t"
- "cmp %[prev], %[old_value] \n\t"
- "bne 1f \n\t"
- "stxr %w[temp], %[new_value], %[ptr] \n\t"
- "cbnz %w[temp], 0b \n\t"
- "1: \n\t"
- "clrex \n\t"
- : [prev]"=&r" (prev),
- [temp]"=&r" (temp),
- [ptr]"+Q" (*ptr)
- : [old_value]"r" (old_value),
- [new_value]"r" (new_value)
- : "memory", "cc"
- ); // NOLINT
+ prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
return prev;
}
@@ -348,8 +281,12 @@ inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
}
inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
- MemoryBarrier();
- *ptr = value;
+ __asm__ __volatile__ ( // NOLINT
+ "stlr %x[value], %[ptr] \n\t"
+ : [ptr]"=Q" (*ptr)
+ : [value]"r" (value)
+ : "memory"
+ ); // NOLINT
}
inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
@@ -357,8 +294,15 @@ inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
}
inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
- Atomic64 value = *ptr;
- MemoryBarrier();
+ Atomic64 value;
+
+ __asm__ __volatile__ ( // NOLINT
+ "ldar %x[value], %[ptr] \n\t"
+ : [value]"=r" (value)
+ : [ptr]"Q" (*ptr)
+ : "memory"
+ ); // NOLINT
+
return value;
}
diff --git a/deps/v8/src/atomicops_internals_arm_gcc.h b/deps/v8/src/atomicops_internals_arm_gcc.h
index 918920d02a..b72ffb6a6d 100644
--- a/deps/v8/src/atomicops_internals_arm_gcc.h
+++ b/deps/v8/src/atomicops_internals_arm_gcc.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file is an internal atomic implementation, use atomicops.h instead.
//
@@ -311,6 +288,14 @@ inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
return *ptr;
}
+// Byte accessors.
+
+inline void NoBarrier_Store(volatile Atomic8* ptr, Atomic8 value) {
+ *ptr = value;
+}
+
+inline Atomic8 NoBarrier_Load(volatile const Atomic8* ptr) { return *ptr; }
+
} } // namespace v8::internal
#endif // V8_ATOMICOPS_INTERNALS_ARM_GCC_H_
diff --git a/deps/v8/src/atomicops_internals_atomicword_compat.h b/deps/v8/src/atomicops_internals_atomicword_compat.h
index 5934f70689..617aa73b53 100644
--- a/deps/v8/src/atomicops_internals_atomicword_compat.h
+++ b/deps/v8/src/atomicops_internals_atomicword_compat.h
@@ -1,29 +1,6 @@
// Copyright 2014 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file is an internal atomic implementation, use atomicops.h instead.
diff --git a/deps/v8/src/atomicops_internals_mac.h b/deps/v8/src/atomicops_internals_mac.h
index 4bd0c09bdf..5e6abe4a46 100644
--- a/deps/v8/src/atomicops_internals_mac.h
+++ b/deps/v8/src/atomicops_internals_mac.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file is an internal atomic implementation, use atomicops.h instead.
@@ -93,6 +70,10 @@ inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
return Acquire_CompareAndSwap(ptr, old_value, new_value);
}
+inline void NoBarrier_Store(volatile Atomic8* ptr, Atomic8 value) {
+ *ptr = value;
+}
+
inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
}
@@ -107,6 +88,10 @@ inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
}
+inline Atomic8 NoBarrier_Load(volatile const Atomic8* ptr) {
+ return *ptr;
+}
+
inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
return *ptr;
}
diff --git a/deps/v8/src/atomicops_internals_mips_gcc.h b/deps/v8/src/atomicops_internals_mips_gcc.h
index cb8f8b9d95..da9f6e9936 100644
--- a/deps/v8/src/atomicops_internals_mips_gcc.h
+++ b/deps/v8/src/atomicops_internals_mips_gcc.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file is an internal atomic implementation, use atomicops.h instead.
@@ -136,6 +113,10 @@ inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
}
+inline void NoBarrier_Store(volatile Atomic8* ptr, Atomic8 value) {
+ *ptr = value;
+}
+
inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
}
@@ -154,6 +135,10 @@ inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
}
+inline Atomic8 NoBarrier_Load(volatile const Atomic8* ptr) {
+ return *ptr;
+}
+
inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
return *ptr;
}
diff --git a/deps/v8/src/atomicops_internals_tsan.h b/deps/v8/src/atomicops_internals_tsan.h
index 1819798a5d..e100812499 100644
--- a/deps/v8/src/atomicops_internals_tsan.h
+++ b/deps/v8/src/atomicops_internals_tsan.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file is an internal atomic implementation for compiler-based
@@ -276,6 +253,10 @@ inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
return cmp;
}
+inline void NoBarrier_Store(volatile Atomic8* ptr, Atomic8 value) {
+ __tsan_atomic8_store(ptr, value, __tsan_memory_order_relaxed);
+}
+
inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
__tsan_atomic32_store(ptr, value, __tsan_memory_order_relaxed);
}
@@ -289,6 +270,10 @@ inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
__tsan_atomic32_store(ptr, value, __tsan_memory_order_release);
}
+inline Atomic8 NoBarrier_Load(volatile const Atomic8* ptr) {
+ return __tsan_atomic8_load(ptr, __tsan_memory_order_relaxed);
+}
+
inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
return __tsan_atomic32_load(ptr, __tsan_memory_order_relaxed);
}
diff --git a/deps/v8/src/atomicops_internals_x86_gcc.cc b/deps/v8/src/atomicops_internals_x86_gcc.cc
index 950b423f41..0b0e04c815 100644
--- a/deps/v8/src/atomicops_internals_x86_gcc.cc
+++ b/deps/v8/src/atomicops_internals_x86_gcc.cc
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This module gets enough CPU information to optimize the
// atomicops module on x86.
@@ -77,10 +54,10 @@ namespace {
void AtomicOps_Internalx86CPUFeaturesInit() {
using v8::internal::AtomicOps_Internalx86CPUFeatures;
- uint32_t eax;
- uint32_t ebx;
- uint32_t ecx;
- uint32_t edx;
+ uint32_t eax = 0;
+ uint32_t ebx = 0;
+ uint32_t ecx = 0;
+ uint32_t edx = 0;
// Get vendor string (issue CPUID with eax = 0)
cpuid(eax, ebx, ecx, edx, 0);
diff --git a/deps/v8/src/atomicops_internals_x86_gcc.h b/deps/v8/src/atomicops_internals_x86_gcc.h
index e58d598fbd..c8950676b4 100644
--- a/deps/v8/src/atomicops_internals_x86_gcc.h
+++ b/deps/v8/src/atomicops_internals_x86_gcc.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file is an internal atomic implementation, use atomicops.h instead.
@@ -107,6 +84,10 @@ inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
}
+inline void NoBarrier_Store(volatile Atomic8* ptr, Atomic8 value) {
+ *ptr = value;
+}
+
inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
}
@@ -152,6 +133,10 @@ inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
// See comments in Atomic64 version of Release_Store(), below.
}
+inline Atomic8 NoBarrier_Load(volatile const Atomic8* ptr) {
+ return *ptr;
+}
+
inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
return *ptr;
}
diff --git a/deps/v8/src/atomicops_internals_x86_msvc.h b/deps/v8/src/atomicops_internals_x86_msvc.h
index ad9cf9d80b..6376666ae7 100644
--- a/deps/v8/src/atomicops_internals_x86_msvc.h
+++ b/deps/v8/src/atomicops_internals_x86_msvc.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file is an internal atomic implementation, use atomicops.h instead.
@@ -100,6 +77,10 @@ inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
}
+inline void NoBarrier_Store(volatile Atomic8* ptr, Atomic8 value) {
+ *ptr = value;
+}
+
inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
}
@@ -114,6 +95,10 @@ inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
// See comments in Atomic64 version of Release_Store() below.
}
+inline Atomic8 NoBarrier_Load(volatile const Atomic8* ptr) {
+ return *ptr;
+}
+
inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
return *ptr;
}
diff --git a/deps/v8/src/base/macros.h b/deps/v8/src/base/macros.h
new file mode 100644
index 0000000000..b99f01b230
--- /dev/null
+++ b/deps/v8/src/base/macros.h
@@ -0,0 +1,76 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_BASE_MACROS_H_
+#define V8_BASE_MACROS_H_
+
+#include "../../include/v8stdint.h"
+
+
+// The expression OFFSET_OF(type, field) computes the byte-offset
+// of the specified field relative to the containing type. This
+// corresponds to 'offsetof' (in stddef.h), except that it doesn't
+// use 0 or NULL, which causes a problem with the compiler warnings
+// we have enabled (which is also why 'offsetof' doesn't seem to work).
+// Here we simply use the non-zero value 4, which seems to work.
+#define OFFSET_OF(type, field) \
+ (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4)
+
+
+// The expression ARRAY_SIZE(a) is a compile-time constant of type
+// size_t which represents the number of elements of the given
+// array. You should only use ARRAY_SIZE on statically allocated
+// arrays.
+#define ARRAY_SIZE(a) \
+ ((sizeof(a) / sizeof(*(a))) / \
+ static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
+
+
+// A macro to disallow the evil copy constructor and operator= functions
+// This should be used in the private: declarations for a class
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&) V8_DELETE; \
+ void operator=(const TypeName&) V8_DELETE
+
+
+// A macro to disallow all the implicit constructors, namely the
+// default constructor, copy constructor and operator= functions.
+//
+// This should be used in the private: declarations for a class
+// that wants to prevent anyone from instantiating it. This is
+// especially useful for classes containing only static methods.
+#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
+ TypeName() V8_DELETE; \
+ DISALLOW_COPY_AND_ASSIGN(TypeName)
+
+
+// Newly written code should use V8_INLINE and V8_NOINLINE directly.
+#define INLINE(declarator) V8_INLINE declarator
+#define NO_INLINE(declarator) V8_NOINLINE declarator
+
+
+// Newly written code should use V8_WARN_UNUSED_RESULT.
+#define MUST_USE_RESULT V8_WARN_UNUSED_RESULT
+
+
+// Define DISABLE_ASAN macros.
+#if defined(__has_feature)
+#if __has_feature(address_sanitizer)
+#define DISABLE_ASAN __attribute__((no_sanitize_address))
+#endif
+#endif
+
+
+#ifndef DISABLE_ASAN
+#define DISABLE_ASAN
+#endif
+
+
+#if V8_CC_GNU
+#define V8_IMMEDIATE_CRASH() __builtin_trap()
+#else
+#define V8_IMMEDIATE_CRASH() ((void(*)())0)()
+#endif
+
+#endif // V8_BASE_MACROS_H_
diff --git a/deps/v8/src/bignum-dtoa.cc b/deps/v8/src/bignum-dtoa.cc
index 2b91122af5..fa80aad4ea 100644
--- a/deps/v8/src/bignum-dtoa.cc
+++ b/deps/v8/src/bignum-dtoa.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <cmath>
diff --git a/deps/v8/src/bignum-dtoa.h b/deps/v8/src/bignum-dtoa.h
index 93ec1f7706..fc160aecd4 100644
--- a/deps/v8/src/bignum-dtoa.h
+++ b/deps/v8/src/bignum-dtoa.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_BIGNUM_DTOA_H_
#define V8_BIGNUM_DTOA_H_
diff --git a/deps/v8/src/bignum.cc b/deps/v8/src/bignum.cc
index af0edde6d5..e47f355301 100644
--- a/deps/v8/src/bignum.cc
+++ b/deps/v8/src/bignum.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "../include/v8stdint.h"
#include "utils.h"
diff --git a/deps/v8/src/bignum.h b/deps/v8/src/bignum.h
index dcc4fa702a..744768f874 100644
--- a/deps/v8/src/bignum.h
+++ b/deps/v8/src/bignum.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_BIGNUM_H_
#define V8_BIGNUM_H_
diff --git a/deps/v8/src/bootstrapper.cc b/deps/v8/src/bootstrapper.cc
index c4d7adfbbd..1e59f725c9 100644
--- a/deps/v8/src/bootstrapper.cc
+++ b/deps/v8/src/bootstrapper.cc
@@ -1,44 +1,12 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "v8.h"
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
-#include "accessors.h"
-#include "api.h"
#include "bootstrapper.h"
-#include "compiler.h"
-#include "debug.h"
-#include "execution.h"
-#include "global-handles.h"
+
+#include "accessors.h"
#include "isolate-inl.h"
-#include "macro-assembler.h"
#include "natives.h"
-#include "objects-visiting.h"
-#include "platform.h"
#include "snapshot.h"
#include "trig-table.h"
#include "extensions/externalize-string-extension.h"
@@ -51,7 +19,6 @@
namespace v8 {
namespace internal {
-
NativesExternalStringResource::NativesExternalStringResource(
Bootstrapper* bootstrapper,
const char* source,
@@ -86,10 +53,10 @@ Handle<String> Bootstrapper::NativesSourceLookup(int index) {
new NativesExternalStringResource(this,
source.start(),
source.length());
- Handle<String> source_code =
- isolate_->factory()->NewExternalStringFromAscii(resource);
// We do not expect this to throw an exception. Change this if it does.
- CHECK_NOT_EMPTY_HANDLE(isolate_, source_code);
+ Handle<String> source_code =
+ isolate_->factory()->NewExternalStringFromAscii(
+ resource).ToHandleChecked();
heap->natives_source_cache()->set(index, *source_code);
}
Handle<Object> cached_source(heap->natives_source_cache()->get(index),
@@ -240,8 +207,11 @@ class Genesis BASE_EMBEDDED {
ElementsKind elements_kind);
bool InstallNatives();
- Handle<JSFunction> InstallTypedArray(const char* name,
- ElementsKind elementsKind);
+ void InstallTypedArray(
+ const char* name,
+ ElementsKind elements_kind,
+ Handle<JSFunction>* fun,
+ Handle<Map>* external_map);
bool InstallExperimentalNatives();
void InstallBuiltinFunctionIds();
void InstallJSFunctionResultCaches();
@@ -361,9 +331,8 @@ Handle<Context> Bootstrapper::CreateEnvironment(
static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
// object.__proto__ = proto;
- Factory* factory = object->GetIsolate()->factory();
Handle<Map> old_to_map = Handle<Map>(object->map());
- Handle<Map> new_to_map = factory->CopyMap(old_to_map);
+ Handle<Map> new_to_map = Map::Copy(old_to_map);
new_to_map->set_prototype(*proto);
object->set_map(*new_to_map);
}
@@ -389,14 +358,14 @@ static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
Factory* factory = isolate->factory();
Handle<String> internalized_name = factory->InternalizeUtf8String(name);
Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
- Handle<JSFunction> function = prototype.is_null() ?
- factory->NewFunctionWithoutPrototype(internalized_name, call_code) :
- factory->NewFunctionWithPrototype(internalized_name,
- type,
- instance_size,
- prototype,
- call_code,
- install_initial_map);
+ Handle<JSFunction> function = prototype.is_null()
+ ? factory->NewFunction(internalized_name, call_code)
+ : factory->NewFunctionWithPrototype(internalized_name,
+ type,
+ instance_size,
+ prototype,
+ call_code,
+ install_initial_map);
PropertyAttributes attributes;
if (target->IsJSBuiltinsObject()) {
attributes =
@@ -404,9 +373,8 @@ static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
} else {
attributes = DONT_ENUM;
}
- CHECK_NOT_EMPTY_HANDLE(isolate,
- JSObject::SetLocalPropertyIgnoreAttributes(
- target, internalized_name, function, attributes));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ target, internalized_name, function, attributes).Check();
if (set_instance_class_name) {
function->shared()->set_instance_class_name(*internalized_name);
}
@@ -418,44 +386,48 @@ static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
void Genesis::SetFunctionInstanceDescriptor(
Handle<Map> map, PrototypePropertyMode prototypeMode) {
int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
- Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(0, size));
- DescriptorArray::WhitenessWitness witness(*descriptors);
-
- Handle<Foreign> length(factory()->NewForeign(&Accessors::FunctionLength));
- Handle<Foreign> name(factory()->NewForeign(&Accessors::FunctionName));
- Handle<Foreign> args(factory()->NewForeign(&Accessors::FunctionArguments));
- Handle<Foreign> caller(factory()->NewForeign(&Accessors::FunctionCaller));
- Handle<Foreign> prototype;
- if (prototypeMode != DONT_ADD_PROTOTYPE) {
- prototype = factory()->NewForeign(&Accessors::FunctionPrototype);
- }
+ Map::EnsureDescriptorSlack(map, size);
+
PropertyAttributes attribs = static_cast<PropertyAttributes>(
DONT_ENUM | DONT_DELETE | READ_ONLY);
- map->set_instance_descriptors(*descriptors);
+ Handle<AccessorInfo> length =
+ Accessors::FunctionLengthInfo(isolate(), attribs);
{ // Add length.
- CallbacksDescriptor d(*factory()->length_string(), *length, attribs);
- map->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(length->name())),
+ length, attribs);
+ map->AppendDescriptor(&d);
}
+ Handle<AccessorInfo> name =
+ Accessors::FunctionNameInfo(isolate(), attribs);
{ // Add name.
- CallbacksDescriptor d(*factory()->name_string(), *name, attribs);
- map->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(name->name())),
+ name, attribs);
+ map->AppendDescriptor(&d);
}
+ Handle<AccessorInfo> args =
+ Accessors::FunctionArgumentsInfo(isolate(), attribs);
{ // Add arguments.
- CallbacksDescriptor d(*factory()->arguments_string(), *args, attribs);
- map->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(args->name())),
+ args, attribs);
+ map->AppendDescriptor(&d);
}
+ Handle<AccessorInfo> caller =
+ Accessors::FunctionCallerInfo(isolate(), attribs);
{ // Add caller.
- CallbacksDescriptor d(*factory()->caller_string(), *caller, attribs);
- map->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(caller->name())),
+ caller, attribs);
+ map->AppendDescriptor(&d);
}
if (prototypeMode != DONT_ADD_PROTOTYPE) {
- // Add prototype.
if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
attribs = static_cast<PropertyAttributes>(attribs & ~READ_ONLY);
}
- CallbacksDescriptor d(*factory()->prototype_string(), *prototype, attribs);
- map->AppendDescriptor(&d, witness);
+ Handle<AccessorInfo> prototype =
+ Accessors::FunctionPrototypeInfo(isolate(), attribs);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(prototype->name())),
+ prototype, attribs);
+ map->AppendDescriptor(&d);
}
}
@@ -495,8 +467,8 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
Handle<String> object_name = factory->Object_string();
{ // --- O b j e c t ---
- Handle<JSFunction> object_fun =
- factory->NewFunction(object_name, factory->null_value());
+ Handle<JSFunction> object_fun = factory->NewFunctionWithPrototype(
+ object_name, factory->null_value());
Handle<Map> object_function_map =
factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
object_fun->set_initial_map(*object_function_map);
@@ -521,17 +493,11 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
// 262 15.3.4.
Handle<String> empty_string =
factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("Empty"));
- Handle<JSFunction> empty_function =
- factory->NewFunctionWithoutPrototype(empty_string, SLOPPY);
+ Handle<Code> code(isolate->builtins()->builtin(Builtins::kEmptyFunction));
+ Handle<JSFunction> empty_function = factory->NewFunction(empty_string, code);
// --- E m p t y ---
- Handle<Code> code =
- Handle<Code>(isolate->builtins()->builtin(
- Builtins::kEmptyFunction));
- empty_function->set_code(*code);
- empty_function->shared()->set_code(*code);
- Handle<String> source =
- factory->NewStringFromOneByte(STATIC_ASCII_VECTOR("() {}"));
+ Handle<String> source = factory->NewStringFromStaticAscii("() {}");
Handle<Script> script = factory->NewScript(source);
script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
empty_function->shared()->set_script(*script);
@@ -557,46 +523,47 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
void Genesis::SetStrictFunctionInstanceDescriptor(
Handle<Map> map, PrototypePropertyMode prototypeMode) {
int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
- Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(0, size));
- DescriptorArray::WhitenessWitness witness(*descriptors);
+ Map::EnsureDescriptorSlack(map, size);
- Handle<Foreign> length(factory()->NewForeign(&Accessors::FunctionLength));
- Handle<Foreign> name(factory()->NewForeign(&Accessors::FunctionName));
Handle<AccessorPair> arguments(factory()->NewAccessorPair());
Handle<AccessorPair> caller(factory()->NewAccessorPair());
- Handle<Foreign> prototype;
- if (prototypeMode != DONT_ADD_PROTOTYPE) {
- prototype = factory()->NewForeign(&Accessors::FunctionPrototype);
- }
PropertyAttributes rw_attribs =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
PropertyAttributes ro_attribs =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
- map->set_instance_descriptors(*descriptors);
+ Handle<AccessorInfo> length =
+ Accessors::FunctionLengthInfo(isolate(), ro_attribs);
{ // Add length.
- CallbacksDescriptor d(*factory()->length_string(), *length, ro_attribs);
- map->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(length->name())),
+ length, ro_attribs);
+ map->AppendDescriptor(&d);
}
+ Handle<AccessorInfo> name =
+ Accessors::FunctionNameInfo(isolate(), ro_attribs);
{ // Add name.
- CallbacksDescriptor d(*factory()->name_string(), *name, ro_attribs);
- map->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(name->name())),
+ name, ro_attribs);
+ map->AppendDescriptor(&d);
}
{ // Add arguments.
- CallbacksDescriptor d(*factory()->arguments_string(), *arguments,
+ CallbacksDescriptor d(factory()->arguments_string(), arguments,
rw_attribs);
- map->AppendDescriptor(&d, witness);
+ map->AppendDescriptor(&d);
}
{ // Add caller.
- CallbacksDescriptor d(*factory()->caller_string(), *caller, rw_attribs);
- map->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(factory()->caller_string(), caller, rw_attribs);
+ map->AppendDescriptor(&d);
}
if (prototypeMode != DONT_ADD_PROTOTYPE) {
// Add prototype.
PropertyAttributes attribs =
prototypeMode == ADD_WRITEABLE_PROTOTYPE ? rw_attribs : ro_attribs;
- CallbacksDescriptor d(*factory()->prototype_string(), *prototype, attribs);
- map->AppendDescriptor(&d, witness);
+ Handle<AccessorInfo> prototype =
+ Accessors::FunctionPrototypeInfo(isolate(), attribs);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(prototype->name())),
+ prototype, attribs);
+ map->AppendDescriptor(&d);
}
}
@@ -606,16 +573,13 @@ Handle<JSFunction> Genesis::GetThrowTypeErrorFunction() {
if (throw_type_error_function.is_null()) {
Handle<String> name = factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("ThrowTypeError"));
- throw_type_error_function =
- factory()->NewFunctionWithoutPrototype(name, SLOPPY);
Handle<Code> code(isolate()->builtins()->builtin(
Builtins::kStrictModePoisonPill));
+ throw_type_error_function = factory()->NewFunction(name, code);
throw_type_error_function->set_map(native_context()->sloppy_function_map());
- throw_type_error_function->set_code(*code);
- throw_type_error_function->shared()->set_code(*code);
throw_type_error_function->shared()->DontAdaptArguments();
- JSObject::PreventExtensions(throw_type_error_function);
+ JSObject::PreventExtensions(throw_type_error_function).Assert();
}
return throw_type_error_function;
}
@@ -757,15 +721,15 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
Handle<JSObject> prototype =
Handle<JSObject>(
JSObject::cast(js_global_function->instance_prototype()));
- CHECK_NOT_EMPTY_HANDLE(isolate(),
- JSObject::SetLocalPropertyIgnoreAttributes(
- prototype, factory()->constructor_string(),
- isolate()->object_function(), NONE));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ prototype, factory()->constructor_string(),
+ isolate()->object_function(), NONE).Check();
} else {
Handle<FunctionTemplateInfo> js_global_constructor(
FunctionTemplateInfo::cast(js_global_template->constructor()));
js_global_function =
factory()->CreateApiFunction(js_global_constructor,
+ factory()->the_hole_value(),
factory()->InnerGlobalObject);
}
@@ -793,6 +757,7 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
FunctionTemplateInfo::cast(data->constructor()));
global_proxy_function =
factory()->CreateApiFunction(global_constructor,
+ factory()->the_hole_value(),
factory()->OuterGlobalObject);
}
@@ -804,15 +769,17 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
// Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
// Return the global proxy.
+ Handle<JSGlobalProxy> global_proxy;
if (global_object.location() != NULL) {
ASSERT(global_object->IsJSGlobalProxy());
- return ReinitializeJSGlobalProxy(
- global_proxy_function,
- Handle<JSGlobalProxy>::cast(global_object));
+ global_proxy = Handle<JSGlobalProxy>::cast(global_object);
+ factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function);
} else {
- return Handle<JSGlobalProxy>::cast(
+ global_proxy = Handle<JSGlobalProxy>::cast(
factory()->NewJSObject(global_proxy_function, TENURED));
+ global_proxy->set_hash(heap()->undefined_value());
}
+ return global_proxy;
}
@@ -836,11 +803,11 @@ void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) {
native_context()->set_security_token(*inner_global);
static const PropertyAttributes attributes =
static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
- ForceSetProperty(builtins_global,
- factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("global")),
- inner_global,
- attributes);
+ Runtime::ForceSetObjectProperty(builtins_global,
+ factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("global")),
+ inner_global,
+ attributes).Assert();
// Set up the reference from the global object to the builtins object.
JSGlobalObject::cast(*inner_global)->set_builtins(*builtins_global);
TransferNamedProperties(inner_global_from_snapshot, inner_global);
@@ -870,10 +837,9 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
Heap* heap = isolate->heap();
Handle<String> object_name = factory->Object_string();
- CHECK_NOT_EMPTY_HANDLE(isolate,
- JSObject::SetLocalPropertyIgnoreAttributes(
- inner_global, object_name,
- isolate->object_function(), DONT_ENUM));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ inner_global, object_name,
+ isolate->object_function(), DONT_ENUM).Check();
Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
@@ -898,19 +864,18 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
// This assert protects an optimization in
// HGraphBuilder::JSArrayBuilder::EmitMapCode()
ASSERT(initial_map->elements_kind() == GetInitialFastElementsKind());
+ Map::EnsureDescriptorSlack(initial_map, 1);
- Handle<DescriptorArray> array_descriptors(
- factory->NewDescriptorArray(0, 1));
- DescriptorArray::WhitenessWitness witness(*array_descriptors);
-
- Handle<Foreign> array_length(factory->NewForeign(&Accessors::ArrayLength));
PropertyAttributes attribs = static_cast<PropertyAttributes>(
DONT_ENUM | DONT_DELETE);
- initial_map->set_instance_descriptors(*array_descriptors);
+ Handle<AccessorInfo> array_length =
+ Accessors::ArrayLengthInfo(isolate, attribs);
{ // Add length.
- CallbacksDescriptor d(*factory->length_string(), *array_length, attribs);
- array_function->initial_map()->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(
+ Handle<Name>(Name::cast(array_length->name())),
+ array_length, attribs);
+ array_function->initial_map()->AppendDescriptor(&d);
}
// array_function is used internally. JS code creating array object should
@@ -922,7 +887,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
// Cache the array maps, needed by ArrayConstructorStub
CacheInitialJSArrayMaps(native_context(), initial_map);
ArrayConstructorStub array_constructor_stub(isolate);
- Handle<Code> code = array_constructor_stub.GetCode(isolate);
+ Handle<Code> code = array_constructor_stub.GetCode();
array_function->shared()->set_construct_stub(*code);
}
@@ -953,19 +918,16 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
Handle<Map> string_map =
Handle<Map>(native_context()->string_function()->initial_map());
- Handle<DescriptorArray> string_descriptors(
- factory->NewDescriptorArray(0, 1));
- DescriptorArray::WhitenessWitness witness(*string_descriptors);
+ Map::EnsureDescriptorSlack(string_map, 1);
- Handle<Foreign> string_length(
- factory->NewForeign(&Accessors::StringLength));
PropertyAttributes attribs = static_cast<PropertyAttributes>(
DONT_ENUM | DONT_DELETE | READ_ONLY);
- string_map->set_instance_descriptors(*string_descriptors);
+ Handle<AccessorInfo> string_length(
+ Accessors::StringLengthInfo(isolate, attribs));
{ // Add length.
- CallbacksDescriptor d(*factory->length_string(), *string_length, attribs);
- string_map->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(factory->length_string(), string_length, attribs);
+ string_map->AppendDescriptor(&d);
}
}
@@ -995,51 +957,49 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
PropertyAttributes final =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
- Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(0, 5);
- DescriptorArray::WhitenessWitness witness(*descriptors);
- initial_map->set_instance_descriptors(*descriptors);
+ Map::EnsureDescriptorSlack(initial_map, 5);
{
// ECMA-262, section 15.10.7.1.
- FieldDescriptor field(heap->source_string(),
+ FieldDescriptor field(factory->source_string(),
JSRegExp::kSourceFieldIndex,
final,
Representation::Tagged());
- initial_map->AppendDescriptor(&field, witness);
+ initial_map->AppendDescriptor(&field);
}
{
// ECMA-262, section 15.10.7.2.
- FieldDescriptor field(heap->global_string(),
+ FieldDescriptor field(factory->global_string(),
JSRegExp::kGlobalFieldIndex,
final,
Representation::Tagged());
- initial_map->AppendDescriptor(&field, witness);
+ initial_map->AppendDescriptor(&field);
}
{
// ECMA-262, section 15.10.7.3.
- FieldDescriptor field(heap->ignore_case_string(),
+ FieldDescriptor field(factory->ignore_case_string(),
JSRegExp::kIgnoreCaseFieldIndex,
final,
Representation::Tagged());
- initial_map->AppendDescriptor(&field, witness);
+ initial_map->AppendDescriptor(&field);
}
{
// ECMA-262, section 15.10.7.4.
- FieldDescriptor field(heap->multiline_string(),
+ FieldDescriptor field(factory->multiline_string(),
JSRegExp::kMultilineFieldIndex,
final,
Representation::Tagged());
- initial_map->AppendDescriptor(&field, witness);
+ initial_map->AppendDescriptor(&field);
}
{
// ECMA-262, section 15.10.7.5.
PropertyAttributes writable =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
- FieldDescriptor field(heap->last_index_string(),
+ FieldDescriptor field(factory->last_index_string(),
JSRegExp::kLastIndexFieldIndex,
writable,
Representation::Tagged());
- initial_map->AppendDescriptor(&field, witness);
+ initial_map->AppendDescriptor(&field);
}
initial_map->set_inobject_properties(5);
@@ -1050,7 +1010,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map));
// RegExp prototype object is itself a RegExp.
- Handle<Map> proto_map = factory->CopyMap(initial_map);
+ Handle<Map> proto_map = Map::Copy(initial_map);
proto_map->set_prototype(native_context()->initial_object_prototype());
Handle<JSObject> proto = factory->NewJSObjectFromMap(proto_map);
proto->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex,
@@ -1072,16 +1032,15 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
{ // -- J S O N
Handle<String> name = factory->InternalizeUtf8String("JSON");
- Handle<JSFunction> cons = factory->NewFunction(name,
- factory->the_hole_value());
+ Handle<JSFunction> cons = factory->NewFunctionWithPrototype(
+ name, factory->the_hole_value());
JSFunction::SetInstancePrototype(cons,
Handle<Object>(native_context()->initial_object_prototype(), isolate));
cons->SetInstanceClassName(*name);
Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
ASSERT(json_object->IsJSObject());
- CHECK_NOT_EMPTY_HANDLE(isolate,
- JSObject::SetLocalPropertyIgnoreAttributes(
- global, name, json_object, DONT_ENUM));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ global, name, json_object, DONT_ENUM).Check();
native_context()->set_json_object(*json_object);
}
@@ -1098,9 +1057,14 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
{ // -- T y p e d A r r a y s
#define INSTALL_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
{ \
- Handle<JSFunction> fun = InstallTypedArray(#Type "Array", \
- TYPE##_ELEMENTS); \
+ Handle<JSFunction> fun; \
+ Handle<Map> external_map; \
+ InstallTypedArray(#Type "Array", \
+ TYPE##_ELEMENTS, \
+ &fun, \
+ &external_map); \
native_context()->set_##type##_array_fun(*fun); \
+ native_context()->set_##type##_array_external_map(*external_map); \
}
TYPED_ARRAYS(INSTALL_TYPED_ARRAY)
#undef INSTALL_TYPED_ARRAY
@@ -1132,11 +1096,9 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
// class_name equals 'Arguments'.
Handle<String> arguments_string = factory->InternalizeOneByteString(
STATIC_ASCII_VECTOR("Arguments"));
- Handle<Code> code = Handle<Code>(
- isolate->builtins()->builtin(Builtins::kIllegal));
- Handle<JSObject> prototype =
- Handle<JSObject>(
- JSObject::cast(native_context()->object_function()->prototype()));
+ Handle<Code> code(isolate->builtins()->builtin(Builtins::kIllegal));
+ Handle<JSObject> prototype(
+ JSObject::cast(native_context()->object_function()->prototype()));
Handle<JSFunction> function =
factory->NewFunctionWithPrototype(arguments_string,
@@ -1153,24 +1115,22 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
native_context()->set_sloppy_arguments_boilerplate(*result);
// Note: length must be added as the first property and
// callee must be added as the second property.
- CHECK_NOT_EMPTY_HANDLE(isolate,
- JSObject::SetLocalPropertyIgnoreAttributes(
- result, factory->length_string(),
- factory->undefined_value(), DONT_ENUM,
- Object::FORCE_TAGGED, FORCE_FIELD));
- CHECK_NOT_EMPTY_HANDLE(isolate,
- JSObject::SetLocalPropertyIgnoreAttributes(
- result, factory->callee_string(),
- factory->undefined_value(), DONT_ENUM,
- Object::FORCE_TAGGED, FORCE_FIELD));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ result, factory->length_string(),
+ factory->undefined_value(), DONT_ENUM,
+ Object::FORCE_TAGGED, FORCE_FIELD).Check();
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ result, factory->callee_string(),
+ factory->undefined_value(), DONT_ENUM,
+ Object::FORCE_TAGGED, FORCE_FIELD).Check();
#ifdef DEBUG
LookupResult lookup(isolate);
- result->LocalLookup(heap->callee_string(), &lookup);
+ result->LocalLookup(factory->callee_string(), &lookup);
ASSERT(lookup.IsField());
ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsCalleeIndex);
- result->LocalLookup(heap->length_string(), &lookup);
+ result->LocalLookup(factory->length_string(), &lookup);
ASSERT(lookup.IsField());
ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsLengthIndex);
@@ -1195,7 +1155,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
Handle<Map> old_map(
native_context()->sloppy_arguments_boilerplate()->map());
- Handle<Map> new_map = factory->CopyMap(old_map);
+ Handle<Map> new_map = Map::Copy(old_map);
new_map->set_pre_allocated_property_fields(2);
Handle<JSObject> result = factory->NewJSObjectFromMap(new_map);
// Set elements kind after allocating the object because
@@ -1227,26 +1187,24 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
Heap::kStrictArgumentsObjectSize);
// Create the descriptor array for the arguments object.
- Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(0, 3);
- DescriptorArray::WhitenessWitness witness(*descriptors);
- map->set_instance_descriptors(*descriptors);
+ Map::EnsureDescriptorSlack(map, 3);
{ // length
FieldDescriptor d(
- *factory->length_string(), 0, DONT_ENUM, Representation::Tagged());
- map->AppendDescriptor(&d, witness);
+ factory->length_string(), 0, DONT_ENUM, Representation::Tagged());
+ map->AppendDescriptor(&d);
}
{ // callee
- CallbacksDescriptor d(*factory->callee_string(),
- *callee,
+ CallbacksDescriptor d(factory->callee_string(),
+ callee,
attributes);
- map->AppendDescriptor(&d, witness);
+ map->AppendDescriptor(&d);
}
{ // caller
- CallbacksDescriptor d(*factory->caller_string(),
- *caller,
+ CallbacksDescriptor d(factory->caller_string(),
+ caller,
attributes);
- map->AppendDescriptor(&d, witness);
+ map->AppendDescriptor(&d);
}
map->set_function_with_prototype(true);
@@ -1263,14 +1221,13 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
native_context()->set_strict_arguments_boilerplate(*result);
// Add length property only for strict mode boilerplate.
- CHECK_NOT_EMPTY_HANDLE(isolate,
- JSObject::SetLocalPropertyIgnoreAttributes(
- result, factory->length_string(),
- factory->undefined_value(), DONT_ENUM));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ result, factory->length_string(),
+ factory->undefined_value(), DONT_ENUM).Check();
#ifdef DEBUG
LookupResult lookup(isolate);
- result->LocalLookup(heap->length_string(), &lookup);
+ result->LocalLookup(factory->length_string(), &lookup);
ASSERT(lookup.IsField());
ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsLengthIndex);
@@ -1330,18 +1287,26 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
}
-Handle<JSFunction> Genesis::InstallTypedArray(
- const char* name, ElementsKind elementsKind) {
+void Genesis::InstallTypedArray(
+ const char* name,
+ ElementsKind elements_kind,
+ Handle<JSFunction>* fun,
+ Handle<Map>* external_map) {
Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
Handle<JSFunction> result = InstallFunction(global, name, JS_TYPED_ARRAY_TYPE,
JSTypedArray::kSize, isolate()->initial_object_prototype(),
Builtins::kIllegal, false, true);
Handle<Map> initial_map = isolate()->factory()->NewMap(
- JS_TYPED_ARRAY_TYPE, JSTypedArray::kSizeWithInternalFields, elementsKind);
+ JS_TYPED_ARRAY_TYPE,
+ JSTypedArray::kSizeWithInternalFields,
+ elements_kind);
result->set_initial_map(*initial_map);
initial_map->set_constructor(*result);
- return result;
+ *fun = result;
+
+ ElementsKind external_kind = GetNextTransitionElementsKind(elements_kind);
+ *external_map = Map::AsElementsKind(initial_map, external_kind);
}
@@ -1371,6 +1336,16 @@ void Genesis::InitializeExperimentalGlobal() {
isolate()->initial_object_prototype(),
Builtins::kIllegal, true, true);
}
+ { // -- S e t I t e r a t o r
+ Handle<Map> map = isolate()->factory()->NewMap(
+ JS_SET_ITERATOR_TYPE, JSSetIterator::kSize);
+ native_context()->set_set_iterator_map(*map);
+ }
+ { // -- M a p I t e r a t o r
+ Handle<Map> map = isolate()->factory()->NewMap(
+ JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize);
+ native_context()->set_map_iterator_map(*map);
+ }
}
if (FLAG_harmony_generators) {
@@ -1391,61 +1366,59 @@ void Genesis::InitializeExperimentalGlobal() {
// Create maps for generator functions and their prototypes. Store those
// maps in the native context.
Handle<Map> function_map(native_context()->sloppy_function_map());
- Handle<Map> generator_function_map = factory()->CopyMap(function_map);
+ Handle<Map> generator_function_map = Map::Copy(function_map);
generator_function_map->set_prototype(*generator_function_prototype);
native_context()->set_sloppy_generator_function_map(
*generator_function_map);
Handle<Map> strict_mode_function_map(
native_context()->strict_function_map());
- Handle<Map> strict_mode_generator_function_map = factory()->CopyMap(
- strict_mode_function_map);
+ Handle<Map> strict_mode_generator_function_map =
+ Map::Copy(strict_mode_function_map);
strict_mode_generator_function_map->set_prototype(
*generator_function_prototype);
native_context()->set_strict_generator_function_map(
*strict_mode_generator_function_map);
- Handle<Map> object_map(native_context()->object_function()->initial_map());
- Handle<Map> generator_object_prototype_map = factory()->CopyMap(
- object_map, 0);
+ Handle<JSFunction> object_function(native_context()->object_function());
+ Handle<Map> generator_object_prototype_map = Map::Create(
+ object_function, 0);
generator_object_prototype_map->set_prototype(
*generator_object_prototype);
native_context()->set_generator_object_prototype_map(
*generator_object_prototype_map);
+ }
- // Create a map for generator result objects.
- ASSERT(object_map->inobject_properties() == 0);
- STATIC_ASSERT(JSGeneratorObject::kResultPropertyCount == 2);
- Handle<Map> generator_result_map = factory()->CopyMap(object_map,
- JSGeneratorObject::kResultPropertyCount);
- ASSERT(generator_result_map->inobject_properties() ==
- JSGeneratorObject::kResultPropertyCount);
+ if (FLAG_harmony_collections || FLAG_harmony_generators) {
+ // Collection forEach uses an iterator result object.
+ // Generators return iteraror result objects.
- Handle<DescriptorArray> descriptors = factory()->NewDescriptorArray(0,
+ STATIC_ASSERT(JSGeneratorObject::kResultPropertyCount == 2);
+ Handle<JSFunction> object_function(native_context()->object_function());
+ ASSERT(object_function->initial_map()->inobject_properties() == 0);
+ Handle<Map> iterator_result_map = Map::Create(
+ object_function, JSGeneratorObject::kResultPropertyCount);
+ ASSERT(iterator_result_map->inobject_properties() ==
JSGeneratorObject::kResultPropertyCount);
- DescriptorArray::WhitenessWitness witness(*descriptors);
- generator_result_map->set_instance_descriptors(*descriptors);
+ Map::EnsureDescriptorSlack(
+ iterator_result_map, JSGeneratorObject::kResultPropertyCount);
- Handle<String> value_string = factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("value"));
- FieldDescriptor value_descr(*value_string,
+ FieldDescriptor value_descr(isolate()->factory()->value_string(),
JSGeneratorObject::kResultValuePropertyIndex,
NONE,
Representation::Tagged());
- generator_result_map->AppendDescriptor(&value_descr, witness);
+ iterator_result_map->AppendDescriptor(&value_descr);
- Handle<String> done_string = factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("done"));
- FieldDescriptor done_descr(*done_string,
+ FieldDescriptor done_descr(isolate()->factory()->done_string(),
JSGeneratorObject::kResultDonePropertyIndex,
NONE,
Representation::Tagged());
- generator_result_map->AppendDescriptor(&done_descr, witness);
+ iterator_result_map->AppendDescriptor(&done_descr);
- generator_result_map->set_unused_property_fields(0);
+ iterator_result_map->set_unused_property_fields(0);
ASSERT_EQ(JSGeneratorObject::kResultSize,
- generator_result_map->instance_size());
- native_context()->set_generator_result_map(*generator_result_map);
+ iterator_result_map->instance_size());
+ native_context()->set_iterator_result_map(*iterator_result_map);
}
}
@@ -1461,10 +1434,12 @@ bool Genesis::CompileBuiltin(Isolate* isolate, int index) {
bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) {
Vector<const char> name = ExperimentalNatives::GetScriptName(index);
Factory* factory = isolate->factory();
- Handle<String> source_code =
+ Handle<String> source_code;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, source_code,
factory->NewStringFromAscii(
- ExperimentalNatives::GetRawScriptSource(index));
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, source_code, false);
+ ExperimentalNatives::GetRawScriptSource(index)),
+ false);
return CompileNative(isolate, name, source_code);
}
@@ -1473,9 +1448,7 @@ bool Genesis::CompileNative(Isolate* isolate,
Vector<const char> name,
Handle<String> source) {
HandleScope scope(isolate);
-#ifdef ENABLE_DEBUGGER_SUPPORT
isolate->debugger()->set_compiling_natives(true);
-#endif
// During genesis, the boilerplate for stack overflow won't work until the
// environment has been at least partially initialized. Add a stack check
// before entering JS code to catch overflow early.
@@ -1491,9 +1464,7 @@ bool Genesis::CompileNative(Isolate* isolate,
true);
ASSERT(isolate->has_pending_exception() != result);
if (!result) isolate->clear_pending_exception();
-#ifdef ENABLE_DEBUGGER_SUPPORT
isolate->debugger()->set_compiling_natives(false);
-#endif
return result;
}
@@ -1513,8 +1484,8 @@ bool Genesis::CompileScriptCached(Isolate* isolate,
// function and insert it into the cache.
if (cache == NULL || !cache->Lookup(name, &function_info)) {
ASSERT(source->IsOneByteRepresentation());
- Handle<String> script_name = factory->NewStringFromUtf8(name);
- ASSERT(!script_name.is_null());
+ Handle<String> script_name =
+ factory->NewStringFromUtf8(name).ToHandleChecked();
function_info = Compiler::CompileScript(
source,
script_name,
@@ -1548,20 +1519,17 @@ bool Genesis::CompileScriptCached(Isolate* isolate,
? top_context->builtins()
: top_context->global_object(),
isolate);
- bool has_pending_exception;
- Execution::Call(isolate, fun, receiver, 0, NULL, &has_pending_exception);
- if (has_pending_exception) return false;
- return true;
+ return !Execution::Call(
+ isolate, fun, receiver, 0, NULL).is_null();
}
-#define INSTALL_NATIVE(Type, name, var) \
- Handle<String> var##_name = \
- factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR(name)); \
- Object* var##_native = \
- native_context()->builtins()->GetPropertyNoExceptionThrown( \
- *var##_name); \
- native_context()->set_##var(Type::cast(var##_native));
+#define INSTALL_NATIVE(Type, name, var) \
+ Handle<String> var##_name = \
+ factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR(name)); \
+ Handle<Object> var##_native = Object::GetProperty( \
+ handle(native_context()->builtins()), var##_name).ToHandleChecked(); \
+ native_context()->set_##var(Type::cast(*var##_native));
void Genesis::InstallNativeFunctions() {
@@ -1598,13 +1566,18 @@ void Genesis::InstallNativeFunctions() {
observers_begin_perform_splice);
INSTALL_NATIVE(JSFunction, "EndPerformSplice",
observers_end_perform_splice);
+ INSTALL_NATIVE(JSFunction, "NativeObjectObserve",
+ native_object_observe);
+ INSTALL_NATIVE(JSFunction, "NativeObjectGetNotifier",
+ native_object_get_notifier);
+ INSTALL_NATIVE(JSFunction, "NativeObjectNotifierPerformChange",
+ native_object_notifier_perform_change);
}
void Genesis::InstallExperimentalNativeFunctions() {
INSTALL_NATIVE(JSFunction, "RunMicrotasks", run_microtasks);
- INSTALL_NATIVE(JSFunction, "EnqueueExternalMicrotask",
- enqueue_external_microtask);
+ INSTALL_NATIVE(JSFunction, "EnqueueMicrotask", enqueue_microtask);
if (FLAG_harmony_proxies) {
INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap);
@@ -1640,30 +1613,27 @@ Handle<JSFunction> Genesis::InstallInternalArray(
Accessors::FunctionSetPrototype(array_function, prototype);
InternalArrayConstructorStub internal_array_constructor_stub(isolate());
- Handle<Code> code = internal_array_constructor_stub.GetCode(isolate());
+ Handle<Code> code = internal_array_constructor_stub.GetCode();
array_function->shared()->set_construct_stub(*code);
array_function->shared()->DontAdaptArguments();
Handle<Map> original_map(array_function->initial_map());
- Handle<Map> initial_map = factory()->CopyMap(original_map);
+ Handle<Map> initial_map = Map::Copy(original_map);
initial_map->set_elements_kind(elements_kind);
array_function->set_initial_map(*initial_map);
// Make "length" magic on instances.
- Handle<DescriptorArray> array_descriptors(
- factory()->NewDescriptorArray(0, 1));
- DescriptorArray::WhitenessWitness witness(*array_descriptors);
+ Map::EnsureDescriptorSlack(initial_map, 1);
- Handle<Foreign> array_length(factory()->NewForeign(
- &Accessors::ArrayLength));
PropertyAttributes attribs = static_cast<PropertyAttributes>(
DONT_ENUM | DONT_DELETE);
- initial_map->set_instance_descriptors(*array_descriptors);
+ Handle<AccessorInfo> array_length =
+ Accessors::ArrayLengthInfo(isolate(), attribs);
{ // Add length.
CallbacksDescriptor d(
- *factory()->length_string(), *array_length, attribs);
- array_function->initial_map()->AppendDescriptor(&d, witness);
+ Handle<Name>(Name::cast(array_length->name())), array_length, attribs);
+ array_function->initial_map()->AppendDescriptor(&d);
}
return array_function;
@@ -1708,23 +1678,20 @@ bool Genesis::InstallNatives() {
Handle<String> global_string =
factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("global"));
Handle<Object> global_obj(native_context()->global_object(), isolate());
- CHECK_NOT_EMPTY_HANDLE(isolate(),
- JSObject::SetLocalPropertyIgnoreAttributes(
- builtins, global_string, global_obj, attributes));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ builtins, global_string, global_obj, attributes).Check();
Handle<String> builtins_string =
factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("builtins"));
- CHECK_NOT_EMPTY_HANDLE(isolate(),
- JSObject::SetLocalPropertyIgnoreAttributes(
- builtins, builtins_string, builtins, attributes));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ builtins, builtins_string, builtins, attributes).Check();
// Set up the reference from the global object to the builtins object.
JSGlobalObject::cast(native_context()->global_object())->
set_builtins(*builtins);
// Create a bridge function that has context in the native context.
- Handle<JSFunction> bridge =
- factory()->NewFunction(factory()->empty_string(),
- factory()->undefined_value());
+ Handle<JSFunction> bridge = factory()->NewFunctionWithPrototype(
+ factory()->empty_string(), factory()->undefined_value());
ASSERT(bridge->context() == *isolate()->native_context());
// Allocate the builtins context.
@@ -1746,132 +1713,111 @@ bool Genesis::InstallNatives() {
native_context()->set_script_function(*script_fun);
Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
+ Map::EnsureDescriptorSlack(script_map, 13);
- Handle<DescriptorArray> script_descriptors(
- factory()->NewDescriptorArray(0, 13));
- DescriptorArray::WhitenessWitness witness(*script_descriptors);
-
- Handle<Foreign> script_source(
- factory()->NewForeign(&Accessors::ScriptSource));
- Handle<Foreign> script_name(factory()->NewForeign(&Accessors::ScriptName));
- Handle<String> id_string(factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("id")));
- Handle<Foreign> script_id(factory()->NewForeign(&Accessors::ScriptId));
- Handle<String> line_offset_string(
- factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("line_offset")));
- Handle<Foreign> script_line_offset(
- factory()->NewForeign(&Accessors::ScriptLineOffset));
- Handle<String> column_offset_string(
- factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("column_offset")));
- Handle<Foreign> script_column_offset(
- factory()->NewForeign(&Accessors::ScriptColumnOffset));
- Handle<String> type_string(factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("type")));
- Handle<Foreign> script_type(factory()->NewForeign(&Accessors::ScriptType));
- Handle<String> compilation_type_string(
- factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("compilation_type")));
- Handle<Foreign> script_compilation_type(
- factory()->NewForeign(&Accessors::ScriptCompilationType));
- Handle<String> line_ends_string(factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("line_ends")));
- Handle<Foreign> script_line_ends(
- factory()->NewForeign(&Accessors::ScriptLineEnds));
- Handle<String> context_data_string(
- factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("context_data")));
- Handle<Foreign> script_context_data(
- factory()->NewForeign(&Accessors::ScriptContextData));
- Handle<String> eval_from_script_string(
- factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("eval_from_script")));
- Handle<Foreign> script_eval_from_script(
- factory()->NewForeign(&Accessors::ScriptEvalFromScript));
- Handle<String> eval_from_script_position_string(
- factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("eval_from_script_position")));
- Handle<Foreign> script_eval_from_script_position(
- factory()->NewForeign(&Accessors::ScriptEvalFromScriptPosition));
- Handle<String> eval_from_function_name_string(
- factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("eval_from_function_name")));
- Handle<Foreign> script_eval_from_function_name(
- factory()->NewForeign(&Accessors::ScriptEvalFromFunctionName));
PropertyAttributes attribs =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
- script_map->set_instance_descriptors(*script_descriptors);
+ Handle<AccessorInfo> script_column =
+ Accessors::ScriptColumnOffsetInfo(isolate(), attribs);
{
- CallbacksDescriptor d(
- *factory()->source_string(), *script_source, attribs);
- script_map->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(script_column->name())),
+ script_column, attribs);
+ script_map->AppendDescriptor(&d);
}
+ Handle<AccessorInfo> script_id =
+ Accessors::ScriptIdInfo(isolate(), attribs);
{
- CallbacksDescriptor d(*factory()->name_string(), *script_name, attribs);
- script_map->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(script_id->name())),
+ script_id, attribs);
+ script_map->AppendDescriptor(&d);
}
+
+ Handle<AccessorInfo> script_name =
+ Accessors::ScriptNameInfo(isolate(), attribs);
{
- CallbacksDescriptor d(*id_string, *script_id, attribs);
- script_map->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(script_name->name())),
+ script_name, attribs);
+ script_map->AppendDescriptor(&d);
}
+ Handle<AccessorInfo> script_line =
+ Accessors::ScriptLineOffsetInfo(isolate(), attribs);
{
- CallbacksDescriptor d(*line_offset_string, *script_line_offset, attribs);
- script_map->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(script_line->name())),
+ script_line, attribs);
+ script_map->AppendDescriptor(&d);
}
+ Handle<AccessorInfo> script_source =
+ Accessors::ScriptSourceInfo(isolate(), attribs);
{
- CallbacksDescriptor d(
- *column_offset_string, *script_column_offset, attribs);
- script_map->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(script_source->name())),
+ script_source, attribs);
+ script_map->AppendDescriptor(&d);
}
+ Handle<AccessorInfo> script_type =
+ Accessors::ScriptTypeInfo(isolate(), attribs);
{
- CallbacksDescriptor d(*type_string, *script_type, attribs);
- script_map->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(script_type->name())),
+ script_type, attribs);
+ script_map->AppendDescriptor(&d);
}
+ Handle<AccessorInfo> script_compilation_type =
+ Accessors::ScriptCompilationTypeInfo(isolate(), attribs);
{
CallbacksDescriptor d(
- *compilation_type_string, *script_compilation_type, attribs);
- script_map->AppendDescriptor(&d, witness);
+ Handle<Name>(Name::cast(script_compilation_type->name())),
+ script_compilation_type, attribs);
+ script_map->AppendDescriptor(&d);
}
+ Handle<AccessorInfo> script_line_ends =
+ Accessors::ScriptLineEndsInfo(isolate(), attribs);
{
- CallbacksDescriptor d(*line_ends_string, *script_line_ends, attribs);
- script_map->AppendDescriptor(&d, witness);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(script_line_ends->name())),
+ script_line_ends, attribs);
+ script_map->AppendDescriptor(&d);
}
+ Handle<AccessorInfo> script_context_data =
+ Accessors::ScriptContextDataInfo(isolate(), attribs);
{
CallbacksDescriptor d(
- *context_data_string, *script_context_data, attribs);
- script_map->AppendDescriptor(&d, witness);
+ Handle<Name>(Name::cast(script_context_data->name())),
+ script_context_data, attribs);
+ script_map->AppendDescriptor(&d);
}
+ Handle<AccessorInfo> script_eval_from_script =
+ Accessors::ScriptEvalFromScriptInfo(isolate(), attribs);
{
CallbacksDescriptor d(
- *eval_from_script_string, *script_eval_from_script, attribs);
- script_map->AppendDescriptor(&d, witness);
+ Handle<Name>(Name::cast(script_eval_from_script->name())),
+ script_eval_from_script, attribs);
+ script_map->AppendDescriptor(&d);
}
+ Handle<AccessorInfo> script_eval_from_script_position =
+ Accessors::ScriptEvalFromScriptPositionInfo(isolate(), attribs);
{
CallbacksDescriptor d(
- *eval_from_script_position_string,
- *script_eval_from_script_position,
- attribs);
- script_map->AppendDescriptor(&d, witness);
+ Handle<Name>(Name::cast(script_eval_from_script_position->name())),
+ script_eval_from_script_position, attribs);
+ script_map->AppendDescriptor(&d);
}
+ Handle<AccessorInfo> script_eval_from_function_name =
+ Accessors::ScriptEvalFromFunctionNameInfo(isolate(), attribs);
{
CallbacksDescriptor d(
- *eval_from_function_name_string,
- *script_eval_from_function_name,
- attribs);
- script_map->AppendDescriptor(&d, witness);
+ Handle<Name>(Name::cast(script_eval_from_function_name->name())),
+ script_eval_from_function_name, attribs);
+ script_map->AppendDescriptor(&d);
}
// Allocate the empty script.
@@ -1938,8 +1884,8 @@ bool Genesis::InstallNatives() {
// Install Function.prototype.call and apply.
{ Handle<String> key = factory()->function_class_string();
Handle<JSFunction> function =
- Handle<JSFunction>::cast(
- GetProperty(isolate(), isolate()->global_object(), key));
+ Handle<JSFunction>::cast(Object::GetProperty(
+ isolate()->global_object(), key).ToHandleChecked());
Handle<JSObject> proto =
Handle<JSObject>(JSObject::cast(function->instance_prototype()));
@@ -1991,38 +1937,36 @@ bool Genesis::InstallNatives() {
initial_map->set_prototype(*array_prototype);
// Update map with length accessor from Array and add "index" and "input".
- Handle<DescriptorArray> reresult_descriptors =
- factory()->NewDescriptorArray(0, 3);
- DescriptorArray::WhitenessWitness witness(*reresult_descriptors);
- initial_map->set_instance_descriptors(*reresult_descriptors);
+ Map::EnsureDescriptorSlack(initial_map, 3);
{
JSFunction* array_function = native_context()->array_function();
Handle<DescriptorArray> array_descriptors(
array_function->initial_map()->instance_descriptors());
- String* length = heap()->length_string();
+ Handle<String> length = factory()->length_string();
int old = array_descriptors->SearchWithCache(
- length, array_function->initial_map());
+ *length, array_function->initial_map());
ASSERT(old != DescriptorArray::kNotFound);
CallbacksDescriptor desc(length,
- array_descriptors->GetValue(old),
+ handle(array_descriptors->GetValue(old),
+ isolate()),
array_descriptors->GetDetails(old).attributes());
- initial_map->AppendDescriptor(&desc, witness);
+ initial_map->AppendDescriptor(&desc);
}
{
- FieldDescriptor index_field(heap()->index_string(),
+ FieldDescriptor index_field(factory()->index_string(),
JSRegExpResult::kIndexIndex,
NONE,
Representation::Tagged());
- initial_map->AppendDescriptor(&index_field, witness);
+ initial_map->AppendDescriptor(&index_field);
}
{
- FieldDescriptor input_field(heap()->input_string(),
+ FieldDescriptor input_field(factory()->input_string(),
JSRegExpResult::kInputIndex,
NONE,
Representation::Tagged());
- initial_map->AppendDescriptor(&input_field, witness);
+ initial_map->AppendDescriptor(&input_field);
}
initial_map->set_inobject_properties(2);
@@ -2033,7 +1977,7 @@ bool Genesis::InstallNatives() {
}
#ifdef VERIFY_HEAP
- builtins->Verify();
+ builtins->ObjectVerify();
#endif
return true;
@@ -2076,8 +2020,8 @@ static Handle<JSObject> ResolveBuiltinIdHolder(
Handle<GlobalObject> global(native_context->global_object());
const char* period_pos = strchr(holder_expr, '.');
if (period_pos == NULL) {
- return Handle<JSObject>::cast(GetProperty(
- isolate, global, factory->InternalizeUtf8String(holder_expr)));
+ return Handle<JSObject>::cast(Object::GetPropertyOrElement(
+ global, factory->InternalizeUtf8String(holder_expr)).ToHandleChecked());
}
ASSERT_EQ(".prototype", period_pos);
Vector<const char> property(holder_expr,
@@ -2085,7 +2029,7 @@ static Handle<JSObject> ResolveBuiltinIdHolder(
Handle<String> property_string = factory->InternalizeUtf8String(property);
ASSERT(!property_string.is_null());
Handle<JSFunction> function = Handle<JSFunction>::cast(
- GetProperty(isolate, global, property_string));
+ Object::GetProperty(global, property_string).ToHandleChecked());
return Handle<JSObject>(JSObject::cast(function->prototype()));
}
@@ -2093,10 +2037,10 @@ static Handle<JSObject> ResolveBuiltinIdHolder(
static void InstallBuiltinFunctionId(Handle<JSObject> holder,
const char* function_name,
BuiltinFunctionId id) {
- Factory* factory = holder->GetIsolate()->factory();
- Handle<String> name = factory->InternalizeUtf8String(function_name);
- Object* function_object = holder->GetProperty(*name)->ToObjectUnchecked();
- Handle<JSFunction> function(JSFunction::cast(function_object));
+ Isolate* isolate = holder->GetIsolate();
+ Handle<Object> function_object =
+ Object::GetProperty(isolate, holder, function_name).ToHandleChecked();
+ Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
function->shared()->set_function_data(Smi::FromInt(id));
}
@@ -2169,9 +2113,8 @@ void Genesis::InstallJSFunctionResultCaches() {
void Genesis::InitializeNormalizedMapCaches() {
- Handle<FixedArray> array(
- factory()->NewFixedArray(NormalizedMapCache::kEntries, TENURED));
- native_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array));
+ Handle<NormalizedMapCache> cache = NormalizedMapCache::New(isolate());
+ native_context()->set_normalized_map_cache(*cache);
}
@@ -2195,23 +2138,27 @@ bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
Handle<String> natives =
factory->InternalizeUtf8String(FLAG_expose_natives_as);
- JSObject::SetLocalPropertyIgnoreAttributes(
- global, natives, Handle<JSObject>(global->builtins()), DONT_ENUM);
- if (isolate->has_pending_exception()) return false;
+ RETURN_ON_EXCEPTION_VALUE(
+ isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ global, natives, Handle<JSObject>(global->builtins()), DONT_ENUM),
+ false);
}
- Handle<Object> Error = GetProperty(global, "Error");
+ Handle<Object> Error = Object::GetProperty(
+ isolate, global, "Error").ToHandleChecked();
if (Error->IsJSObject()) {
Handle<String> name = factory->InternalizeOneByteString(
STATIC_ASCII_VECTOR("stackTraceLimit"));
Handle<Smi> stack_trace_limit(
Smi::FromInt(FLAG_stack_trace_limit), isolate);
- JSObject::SetLocalPropertyIgnoreAttributes(
- Handle<JSObject>::cast(Error), name, stack_trace_limit, NONE);
- if (isolate->has_pending_exception()) return false;
+ RETURN_ON_EXCEPTION_VALUE(
+ isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ Handle<JSObject>::cast(Error), name, stack_trace_limit, NONE),
+ false);
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
// Expose the debug global object in global if a name for it is specified.
if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
Debug* debug = isolate->debug();
@@ -2228,11 +2175,12 @@ bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
factory->InternalizeUtf8String(FLAG_expose_debug_as);
Handle<Object> global_proxy(
debug->debug_context()->global_proxy(), isolate);
- JSObject::SetLocalPropertyIgnoreAttributes(
- global, debug_string, global_proxy, DONT_ENUM);
- if (isolate->has_pending_exception()) return false;
+ RETURN_ON_EXCEPTION_VALUE(
+ isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ global, debug_string, global_proxy, DONT_ENUM),
+ false);
}
-#endif
return true;
}
@@ -2242,12 +2190,7 @@ static uint32_t Hash(RegisteredExtension* extension) {
}
-static bool MatchRegisteredExtensions(void* key1, void* key2) {
- return key1 == key2;
-}
-
-Genesis::ExtensionStates::ExtensionStates()
- : map_(MatchRegisteredExtensions, 8) { }
+Genesis::ExtensionStates::ExtensionStates() : map_(HashMap::PointersMatch, 8) {}
Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state(
RegisteredExtension* extension) {
@@ -2351,10 +2294,10 @@ bool Genesis::InstallExtension(Isolate* isolate,
return false;
}
}
- Handle<String> source_code =
- isolate->factory()->NewExternalStringFromAscii(extension->source());
// We do not expect this to throw an exception. Change this if it does.
- CHECK_NOT_EMPTY_HANDLE(isolate, source_code);
+ Handle<String> source_code =
+ isolate->factory()->NewExternalStringFromAscii(
+ extension->source()).ToHandleChecked();
bool result = CompileScriptCached(isolate,
CStrVector(extension->name()),
source_code,
@@ -2382,11 +2325,9 @@ bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
HandleScope scope(isolate());
for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
- Handle<String> name =
- factory()->InternalizeUtf8String(Builtins::GetName(id));
- Object* function_object = builtins->GetPropertyNoExceptionThrown(*name);
- Handle<JSFunction> function
- = Handle<JSFunction>(JSFunction::cast(function_object));
+ Handle<Object> function_object = Object::GetProperty(
+ isolate(), builtins, Builtins::GetName(id)).ToHandleChecked();
+ Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
builtins->set_javascript_builtin(id, *function);
if (!Compiler::EnsureCompiled(function, CLEAR_EXCEPTION)) {
return false;
@@ -2435,10 +2376,10 @@ bool Genesis::ConfigureApiObject(Handle<JSObject> object,
ASSERT(FunctionTemplateInfo::cast(object_template->constructor())
->IsTemplateFor(object->map()));;
- bool pending_exception = false;
- Handle<JSObject> obj =
- Execution::InstantiateObject(object_template, &pending_exception);
- if (pending_exception) {
+ MaybeHandle<JSObject> maybe_obj =
+ Execution::InstantiateObject(object_template);
+ Handle<JSObject> obj;
+ if (!maybe_obj.ToHandle(&obj)) {
ASSERT(isolate()->has_pending_exception());
isolate()->clear_pending_exception();
return false;
@@ -2463,29 +2404,27 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
ASSERT(!descs->GetDetails(i).representation().IsDouble());
Handle<Object> value = Handle<Object>(from->RawFastPropertyAt(index),
isolate());
- CHECK_NOT_EMPTY_HANDLE(isolate(),
- JSObject::SetLocalPropertyIgnoreAttributes(
- to, key, value, details.attributes()));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ to, key, value, details.attributes()).Check();
break;
}
case CONSTANT: {
HandleScope inner(isolate());
Handle<Name> key = Handle<Name>(descs->GetKey(i));
Handle<Object> constant(descs->GetConstant(i), isolate());
- CHECK_NOT_EMPTY_HANDLE(isolate(),
- JSObject::SetLocalPropertyIgnoreAttributes(
- to, key, constant, details.attributes()));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ to, key, constant, details.attributes()).Check();
break;
}
case CALLBACKS: {
LookupResult result(isolate());
- to->LocalLookup(descs->GetKey(i), &result);
+ Handle<Name> key(Name::cast(descs->GetKey(i)), isolate());
+ to->LocalLookup(key, &result);
// If the property is already there we skip it
if (result.IsFound()) continue;
HandleScope inner(isolate());
ASSERT(!to->HasFastProperties());
// Add to dictionary.
- Handle<Name> key = Handle<Name>(descs->GetKey(i));
Handle<Object> callbacks(descs->GetCallbacksObject(i), isolate());
PropertyDetails d = PropertyDetails(
details.attributes(), CALLBACKS, i + 1);
@@ -2496,7 +2435,6 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
// Do not occur since the from object has fast properties.
case HANDLER:
case INTERCEPTOR:
- case TRANSITION:
case NONEXISTENT:
// No element in instance descriptors have proxy or interceptor type.
UNREACHABLE();
@@ -2513,10 +2451,10 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
ASSERT(raw_key->IsName());
// If the property is already there we skip it.
LookupResult result(isolate());
- to->LocalLookup(Name::cast(raw_key), &result);
+ Handle<Name> key(Name::cast(raw_key));
+ to->LocalLookup(key, &result);
if (result.IsFound()) continue;
// Set the property.
- Handle<Name> key = Handle<Name>(Name::cast(raw_key));
Handle<Object> value = Handle<Object>(properties->ValueAt(i),
isolate());
ASSERT(!value->IsCell());
@@ -2525,9 +2463,8 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
isolate());
}
PropertyDetails details = properties->DetailsAt(i);
- CHECK_NOT_EMPTY_HANDLE(isolate(),
- JSObject::SetLocalPropertyIgnoreAttributes(
- to, key, value, details.attributes()));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ to, key, value, details.attributes()).Check();
}
}
}
@@ -2555,7 +2492,7 @@ void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
// Transfer the prototype (new map is needed).
Handle<Map> old_to_map = Handle<Map>(to->map());
- Handle<Map> new_to_map = factory()->CopyMap(old_to_map);
+ Handle<Map> new_to_map = Map::Copy(old_to_map);
new_to_map->set_prototype(from->map()->prototype());
to->set_map(*new_to_map);
}
@@ -2578,20 +2515,23 @@ void Genesis::MakeFunctionInstancePrototypeWritable() {
class NoTrackDoubleFieldsForSerializerScope {
public:
- NoTrackDoubleFieldsForSerializerScope() : flag_(FLAG_track_double_fields) {
- if (Serializer::enabled()) {
+ explicit NoTrackDoubleFieldsForSerializerScope(Isolate* isolate)
+ : isolate_(isolate), flag_(FLAG_track_double_fields) {
+ if (Serializer::enabled(isolate)) {
// Disable tracking double fields because heap numbers treated as
// immutable by the serializer.
FLAG_track_double_fields = false;
}
}
+
~NoTrackDoubleFieldsForSerializerScope() {
- if (Serializer::enabled()) {
+ if (Serializer::enabled(isolate_)) {
FLAG_track_double_fields = flag_;
}
}
private:
+ Isolate* isolate_;
bool flag_;
};
@@ -2602,7 +2542,7 @@ Genesis::Genesis(Isolate* isolate,
v8::ExtensionConfiguration* extensions)
: isolate_(isolate),
active_(isolate->bootstrapper()) {
- NoTrackDoubleFieldsForSerializerScope disable_double_tracking_for_serializer;
+ NoTrackDoubleFieldsForSerializerScope disable_scope(isolate);
result_ = Handle<Context>::null();
// If V8 cannot be initialized, just return.
if (!V8::Initialize(NULL)) return;
@@ -2668,7 +2608,7 @@ Genesis::Genesis(Isolate* isolate,
// We can't (de-)serialize typed arrays currently, but we are lucky: The state
// of the random number generator needs no initialization during snapshot
// creation time and we don't need trigonometric functions then.
- if (!Serializer::enabled()) {
+ if (!Serializer::enabled(isolate)) {
// Initially seed the per-context random number generator using the
// per-isolate random number generator.
const int num_elems = 2;
@@ -2684,11 +2624,11 @@ Genesis::Genesis(Isolate* isolate,
Utils::OpenHandle(*buffer)->set_should_be_freed(true);
v8::Local<v8::Uint32Array> ta = v8::Uint32Array::New(buffer, 0, num_elems);
Handle<JSBuiltinsObject> builtins(native_context()->builtins());
- ForceSetProperty(builtins,
- factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("rngstate")),
- Utils::OpenHandle(*ta),
- NONE);
+ Runtime::ForceSetObjectProperty(builtins,
+ factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("rngstate")),
+ Utils::OpenHandle(*ta),
+ NONE).Assert();
// Initialize trigonometric lookup tables and constants.
const int table_num_bytes = TrigonometricLookupTable::table_num_bytes();
@@ -2703,28 +2643,31 @@ Genesis::Genesis(Isolate* isolate,
v8::Local<v8::Float64Array> cos_table = v8::Float64Array::New(
cos_buffer, 0, TrigonometricLookupTable::table_size());
- ForceSetProperty(builtins,
- factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("kSinTable")),
- Utils::OpenHandle(*sin_table),
- NONE);
- ForceSetProperty(builtins,
- factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("kCosXIntervalTable")),
- Utils::OpenHandle(*cos_table),
- NONE);
- ForceSetProperty(builtins,
- factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("kSamples")),
- factory()->NewHeapNumber(
- TrigonometricLookupTable::samples()),
- NONE);
- ForceSetProperty(builtins,
- factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("kIndexConvert")),
- factory()->NewHeapNumber(
- TrigonometricLookupTable::samples_over_pi_half()),
- NONE);
+ Runtime::ForceSetObjectProperty(builtins,
+ factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("kSinTable")),
+ Utils::OpenHandle(*sin_table),
+ NONE).Assert();
+ Runtime::ForceSetObjectProperty(
+ builtins,
+ factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("kCosXIntervalTable")),
+ Utils::OpenHandle(*cos_table),
+ NONE).Assert();
+ Runtime::ForceSetObjectProperty(
+ builtins,
+ factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("kSamples")),
+ factory()->NewHeapNumber(
+ TrigonometricLookupTable::samples()),
+ NONE).Assert();
+ Runtime::ForceSetObjectProperty(
+ builtins,
+ factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("kIndexConvert")),
+ factory()->NewHeapNumber(
+ TrigonometricLookupTable::samples_over_pi_half()),
+ NONE).Assert();
}
result_ = native_context();
diff --git a/deps/v8/src/bootstrapper.h b/deps/v8/src/bootstrapper.h
index e683a45f04..f6fcd02ef6 100644
--- a/deps/v8/src/bootstrapper.h
+++ b/deps/v8/src/bootstrapper.h
@@ -1,46 +1,21 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_BOOTSTRAPPER_H_
#define V8_BOOTSTRAPPER_H_
-#include "allocation.h"
+#include "factory.h"
namespace v8 {
namespace internal {
-
// A SourceCodeCache uses a FixedArray to store pairs of
// (AsciiString*, JSFunction*), mapping names of native code files
// (runtime.js, etc.) to precompiled functions. Instead of mapping
// names to functions it might make sense to let the JS2C tool
// generate an index for each native JS file.
-class SourceCodeCache BASE_EMBEDDED {
+class SourceCodeCache V8_FINAL BASE_EMBEDDED {
public:
explicit SourceCodeCache(Script::Type type): type_(type), cache_(NULL) { }
@@ -72,7 +47,8 @@ class SourceCodeCache BASE_EMBEDDED {
Handle<FixedArray> new_array = factory->NewFixedArray(length + 2, TENURED);
cache_->CopyTo(0, *new_array, 0, cache_->length());
cache_ = *new_array;
- Handle<String> str = factory->NewStringFromAscii(name, TENURED);
+ Handle<String> str =
+ factory->NewStringFromAscii(name, TENURED).ToHandleChecked();
ASSERT(!str.is_null());
cache_->set(length, *str);
cache_->set(length + 1, *shared);
@@ -88,7 +64,7 @@ class SourceCodeCache BASE_EMBEDDED {
// The Boostrapper is the public interface for creating a JavaScript global
// context.
-class Bootstrapper {
+class Bootstrapper V8_FINAL {
public:
static void InitializeOncePerProcess();
static void TearDownExtensions();
@@ -158,7 +134,7 @@ class Bootstrapper {
};
-class BootstrapperActive BASE_EMBEDDED {
+class BootstrapperActive V8_FINAL BASE_EMBEDDED {
public:
explicit BootstrapperActive(Bootstrapper* bootstrapper)
: bootstrapper_(bootstrapper) {
@@ -176,20 +152,15 @@ class BootstrapperActive BASE_EMBEDDED {
};
-class NativesExternalStringResource
+class NativesExternalStringResource V8_FINAL
: public v8::String::ExternalAsciiStringResource {
public:
NativesExternalStringResource(Bootstrapper* bootstrapper,
const char* source,
size_t length);
+ virtual const char* data() const V8_OVERRIDE { return data_; }
+ virtual size_t length() const V8_OVERRIDE { return length_; }
- const char* data() const {
- return data_;
- }
-
- size_t length() const {
- return length_;
- }
private:
const char* data_;
size_t length_;
diff --git a/deps/v8/src/builtins.cc b/deps/v8/src/builtins.cc
index 689e845ba8..d0c1a446a8 100644
--- a/deps/v8/src/builtins.cc
+++ b/deps/v8/src/builtins.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -127,28 +104,28 @@ BUILTIN_LIST_C(DEF_ARG_TYPE)
#ifdef DEBUG
#define BUILTIN(name) \
- MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
+ MUST_USE_RESULT static Object* Builtin_Impl_##name( \
name##ArgumentsType args, Isolate* isolate); \
- MUST_USE_RESULT static MaybeObject* Builtin_##name( \
+ MUST_USE_RESULT static Object* Builtin_##name( \
int args_length, Object** args_object, Isolate* isolate) { \
name##ArgumentsType args(args_length, args_object); \
args.Verify(); \
return Builtin_Impl_##name(args, isolate); \
} \
- MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
+ MUST_USE_RESULT static Object* Builtin_Impl_##name( \
name##ArgumentsType args, Isolate* isolate)
#else // For release mode.
#define BUILTIN(name) \
- static MaybeObject* Builtin_impl##name( \
+ static Object* Builtin_impl##name( \
name##ArgumentsType args, Isolate* isolate); \
- static MaybeObject* Builtin_##name( \
+ static Object* Builtin_##name( \
int args_length, Object** args_object, Isolate* isolate) { \
name##ArgumentsType args(args_length, args_object); \
return Builtin_impl##name(args, isolate); \
} \
- static MaybeObject* Builtin_impl##name( \
+ static Object* Builtin_impl##name( \
name##ArgumentsType args, Isolate* isolate)
#endif
@@ -207,22 +184,11 @@ static void MoveDoubleElements(FixedDoubleArray* dst,
}
-static void FillWithHoles(Heap* heap, FixedArray* dst, int from, int to) {
- ASSERT(dst->map() != heap->fixed_cow_array_map());
- MemsetPointer(dst->data_start() + from, heap->the_hole_value(), to - from);
-}
-
-
-static void FillWithHoles(FixedDoubleArray* dst, int from, int to) {
- for (int i = from; i < to; i++) {
- dst->set_the_hole(i);
- }
-}
-
-
static FixedArrayBase* LeftTrimFixedArray(Heap* heap,
FixedArrayBase* elms,
int to_trim) {
+ ASSERT(heap->CanMoveObjectStart(elms));
+
Map* map = elms->map();
int entry_size;
if (elms->IsFixedArray()) {
@@ -259,6 +225,8 @@ static FixedArrayBase* LeftTrimFixedArray(Heap* heap,
// Technically in new space this write might be omitted (except for
// debug mode which iterates through the heap), but to play safer
// we still do it.
+ // Since left trimming is only performed on pages which are not concurrently
+ // swept creating a filler object does not require synchronization.
heap->CreateFillerObjectAt(elms->address(), to_trim * entry_size);
int new_start_index = to_trim * (entry_size / kPointerSize);
@@ -287,6 +255,7 @@ static FixedArrayBase* LeftTrimFixedArray(Heap* heap,
static bool ArrayPrototypeHasNoElements(Heap* heap,
Context* native_context,
JSObject* array_proto) {
+ DisallowHeapAllocation no_gc;
// This method depends on non writability of Object and Array prototype
// fields.
if (array_proto->elements() != heap->empty_fixed_array()) return false;
@@ -302,16 +271,21 @@ static bool ArrayPrototypeHasNoElements(Heap* heap,
// Returns empty handle if not applicable.
MUST_USE_RESULT
-static inline Handle<FixedArrayBase> EnsureJSArrayWithWritableFastElements(
+static inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements(
Isolate* isolate,
Handle<Object> receiver,
Arguments* args,
int first_added_arg) {
- if (!receiver->IsJSArray()) return Handle<FixedArrayBase>::null();
+ if (!receiver->IsJSArray()) return MaybeHandle<FixedArrayBase>();
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
- if (array->map()->is_observed()) return Handle<FixedArrayBase>::null();
- if (!array->map()->is_extensible()) return Handle<FixedArrayBase>::null();
- Handle<FixedArrayBase> elms(array->elements());
+ // If there may be elements accessors in the prototype chain, the fast path
+ // cannot be used if there arguments to add to the array.
+ if (args != NULL && array->map()->DictionaryElementsInPrototypeChainOnly()) {
+ return MaybeHandle<FixedArrayBase>();
+ }
+ if (array->map()->is_observed()) return MaybeHandle<FixedArrayBase>();
+ if (!array->map()->is_extensible()) return MaybeHandle<FixedArrayBase>();
+ Handle<FixedArrayBase> elms(array->elements(), isolate);
Heap* heap = isolate->heap();
Map* map = elms->map();
if (map == heap->fixed_array_map()) {
@@ -322,42 +296,45 @@ static inline Handle<FixedArrayBase> EnsureJSArrayWithWritableFastElements(
} else if (map == heap->fixed_double_array_map()) {
if (args == NULL) return elms;
} else {
- return Handle<FixedArrayBase>::null();
+ return MaybeHandle<FixedArrayBase>();
}
// Need to ensure that the arguments passed in args can be contained in
// the array.
int args_length = args->length();
- if (first_added_arg >= args_length) return handle(array->elements());
+ if (first_added_arg >= args_length) return handle(array->elements(), isolate);
ElementsKind origin_kind = array->map()->elements_kind();
ASSERT(!IsFastObjectElementsKind(origin_kind));
ElementsKind target_kind = origin_kind;
- int arg_count = args->length() - first_added_arg;
- Object** arguments = args->arguments() - first_added_arg - (arg_count - 1);
- for (int i = 0; i < arg_count; i++) {
- Object* arg = arguments[i];
- if (arg->IsHeapObject()) {
- if (arg->IsHeapNumber()) {
- target_kind = FAST_DOUBLE_ELEMENTS;
- } else {
- target_kind = FAST_ELEMENTS;
- break;
+ {
+ DisallowHeapAllocation no_gc;
+ int arg_count = args->length() - first_added_arg;
+ Object** arguments = args->arguments() - first_added_arg - (arg_count - 1);
+ for (int i = 0; i < arg_count; i++) {
+ Object* arg = arguments[i];
+ if (arg->IsHeapObject()) {
+ if (arg->IsHeapNumber()) {
+ target_kind = FAST_DOUBLE_ELEMENTS;
+ } else {
+ target_kind = FAST_ELEMENTS;
+ break;
+ }
}
}
}
if (target_kind != origin_kind) {
JSObject::TransitionElementsKind(array, target_kind);
- return handle(array->elements());
+ return handle(array->elements(), isolate);
}
return elms;
}
-// TODO(ishell): Handlify when all Array* builtins are handlified.
static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap,
JSArray* receiver) {
if (!FLAG_clever_optimizations) return false;
+ DisallowHeapAllocation no_gc;
Context* native_context = heap->isolate()->context()->native_context();
JSObject* array_proto =
JSObject::cast(native_context->array_function()->prototype());
@@ -366,29 +343,30 @@ static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap,
}
-MUST_USE_RESULT static MaybeObject* CallJsBuiltin(
+MUST_USE_RESULT static Object* CallJsBuiltin(
Isolate* isolate,
const char* name,
BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
HandleScope handleScope(isolate);
- Handle<Object> js_builtin =
- GetProperty(Handle<JSObject>(isolate->native_context()->builtins()),
- name);
+ Handle<Object> js_builtin = Object::GetProperty(
+ isolate,
+ handle(isolate->native_context()->builtins(), isolate),
+ name).ToHandleChecked();
Handle<JSFunction> function = Handle<JSFunction>::cast(js_builtin);
int argc = args.length() - 1;
ScopedVector<Handle<Object> > argv(argc);
for (int i = 0; i < argc; ++i) {
argv[i] = args.at<Object>(i + 1);
}
- bool pending_exception;
- Handle<Object> result = Execution::Call(isolate,
- function,
- args.receiver(),
- argc,
- argv.start(),
- &pending_exception);
- if (pending_exception) return Failure::Exception();
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Execution::Call(isolate,
+ function,
+ args.receiver(),
+ argc,
+ argv.start()));
return *result;
}
@@ -396,9 +374,12 @@ MUST_USE_RESULT static MaybeObject* CallJsBuiltin(
BUILTIN(ArrayPush) {
HandleScope scope(isolate);
Handle<Object> receiver = args.receiver();
- Handle<FixedArrayBase> elms_obj =
+ MaybeHandle<FixedArrayBase> maybe_elms_obj =
EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
- if (elms_obj.is_null()) return CallJsBuiltin(isolate, "ArrayPush", args);
+ Handle<FixedArrayBase> elms_obj;
+ if (!maybe_elms_obj.ToHandle(&elms_obj)) {
+ return CallJsBuiltin(isolate, "ArrayPush", args);
+ }
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
ASSERT(!array->map()->is_observed());
@@ -427,8 +408,8 @@ BUILTIN(ArrayPush) {
ElementsAccessor* accessor = array->GetElementsAccessor();
accessor->CopyElements(
- Handle<JSObject>::null(), 0, kind, new_elms, 0,
- ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj);
+ elms_obj, 0, kind, new_elms, 0,
+ ElementsAccessor::kCopyToEndAndInitializeToHole);
elms = new_elms;
}
@@ -466,12 +447,15 @@ BUILTIN(ArrayPush) {
if (new_length > elms_len) {
// New backing storage is needed.
int capacity = new_length + (new_length >> 1) + 16;
- new_elms = isolate->factory()->NewFixedDoubleArray(capacity);
+ // Create new backing store; since capacity > 0, we can
+ // safely cast to FixedDoubleArray.
+ new_elms = Handle<FixedDoubleArray>::cast(
+ isolate->factory()->NewFixedDoubleArray(capacity));
ElementsAccessor* accessor = array->GetElementsAccessor();
accessor->CopyElements(
- Handle<JSObject>::null(), 0, kind, new_elms, 0,
- ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj);
+ elms_obj, 0, kind, new_elms, 0,
+ ElementsAccessor::kCopyToEndAndInitializeToHole);
} else {
// to_add is > 0 and new_length <= elms_len, so elms_obj cannot be the
@@ -498,24 +482,15 @@ BUILTIN(ArrayPush) {
}
-// TODO(ishell): Temporary wrapper until handlified.
-static bool ElementsAccessorHasElementWrapper(
- ElementsAccessor* accessor,
- Handle<Object> receiver,
- Handle<JSObject> holder,
- uint32_t key,
- Handle<FixedArrayBase> backing_store = Handle<FixedArrayBase>::null()) {
- return accessor->HasElement(*receiver, *holder, key,
- backing_store.is_null() ? NULL : *backing_store);
-}
-
-
BUILTIN(ArrayPop) {
HandleScope scope(isolate);
Handle<Object> receiver = args.receiver();
- Handle<FixedArrayBase> elms_obj =
+ MaybeHandle<FixedArrayBase> maybe_elms_obj =
EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
- if (elms_obj.is_null()) return CallJsBuiltin(isolate, "ArrayPop", args);
+ Handle<FixedArrayBase> elms_obj;
+ if (!maybe_elms_obj.ToHandle(&elms_obj)) {
+ return CallJsBuiltin(isolate, "ArrayPop", args);
+ }
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
ASSERT(!array->map()->is_observed());
@@ -525,19 +500,14 @@ BUILTIN(ArrayPop) {
ElementsAccessor* accessor = array->GetElementsAccessor();
int new_length = len - 1;
- Handle<Object> element;
- if (ElementsAccessorHasElementWrapper(
- accessor, array, array, new_length, elms_obj)) {
- element = accessor->Get(
- array, array, new_length, elms_obj);
- } else {
- Handle<Object> proto(array->GetPrototype(), isolate);
- element = Object::GetElement(isolate, proto, len - 1);
+ Handle<Object> element =
+ accessor->Get(array, array, new_length, elms_obj).ToHandleChecked();
+ if (element->IsTheHole()) {
+ return CallJsBuiltin(isolate, "ArrayPop", args);
}
- RETURN_IF_EMPTY_HANDLE(isolate, element);
- RETURN_IF_EMPTY_HANDLE(isolate,
- accessor->SetLength(
- array, handle(Smi::FromInt(new_length), isolate)));
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ accessor->SetLength(array, handle(Smi::FromInt(new_length), isolate)));
return *element;
}
@@ -546,9 +516,10 @@ BUILTIN(ArrayShift) {
HandleScope scope(isolate);
Heap* heap = isolate->heap();
Handle<Object> receiver = args.receiver();
- Handle<FixedArrayBase> elms_obj =
+ MaybeHandle<FixedArrayBase> maybe_elms_obj =
EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
- if (elms_obj.is_null() ||
+ Handle<FixedArrayBase> elms_obj;
+ if (!maybe_elms_obj.ToHandle(&elms_obj) ||
!IsJSArrayFastElementMovingAllowed(heap,
*Handle<JSArray>::cast(receiver))) {
return CallJsBuiltin(isolate, "ArrayShift", args);
@@ -561,13 +532,13 @@ BUILTIN(ArrayShift) {
// Get first element
ElementsAccessor* accessor = array->GetElementsAccessor();
- Handle<Object> first = accessor->Get(receiver, array, 0, elms_obj);
- RETURN_IF_EMPTY_HANDLE(isolate, first);
+ Handle<Object> first =
+ accessor->Get(array, array, 0, elms_obj).ToHandleChecked();
if (first->IsTheHole()) {
- first = isolate->factory()->undefined_value();
+ return CallJsBuiltin(isolate, "ArrayShift", args);
}
- if (!heap->CanMoveObjectStart(*elms_obj)) {
+ if (heap->CanMoveObjectStart(*elms_obj)) {
array->set_elements(LeftTrimFixedArray(heap, *elms_obj, 1));
} else {
// Shift the elements.
@@ -594,9 +565,10 @@ BUILTIN(ArrayUnshift) {
HandleScope scope(isolate);
Heap* heap = isolate->heap();
Handle<Object> receiver = args.receiver();
- Handle<FixedArrayBase> elms_obj =
+ MaybeHandle<FixedArrayBase> maybe_elms_obj =
EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
- if (elms_obj.is_null() ||
+ Handle<FixedArrayBase> elms_obj;
+ if (!maybe_elms_obj.ToHandle(&elms_obj) ||
!IsJSArrayFastElementMovingAllowed(heap,
*Handle<JSArray>::cast(receiver))) {
return CallJsBuiltin(isolate, "ArrayUnshift", args);
@@ -627,8 +599,8 @@ BUILTIN(ArrayUnshift) {
ElementsKind kind = array->GetElementsKind();
ElementsAccessor* accessor = array->GetElementsAccessor();
accessor->CopyElements(
- Handle<JSObject>::null(), 0, kind, new_elms, to_add,
- ElementsAccessor::kCopyToEndAndInitializeToHole, elms);
+ elms, 0, kind, new_elms, to_add,
+ ElementsAccessor::kCopyToEndAndInitializeToHole);
elms = new_elms;
array->set_elements(*elms);
@@ -654,87 +626,95 @@ BUILTIN(ArraySlice) {
HandleScope scope(isolate);
Heap* heap = isolate->heap();
Handle<Object> receiver = args.receiver();
- Handle<FixedArrayBase> elms;
int len = -1;
- if (receiver->IsJSArray()) {
- Handle<JSArray> array = Handle<JSArray>::cast(receiver);
- if (!IsJSArrayFastElementMovingAllowed(heap, *array)) {
- return CallJsBuiltin(isolate, "ArraySlice", args);
- }
-
- if (array->HasFastElements()) {
- elms = handle(array->elements());
- } else {
- return CallJsBuiltin(isolate, "ArraySlice", args);
- }
+ int relative_start = 0;
+ int relative_end = 0;
+ {
+ DisallowHeapAllocation no_gc;
+ if (receiver->IsJSArray()) {
+ JSArray* array = JSArray::cast(*receiver);
+ if (!IsJSArrayFastElementMovingAllowed(heap, array)) {
+ AllowHeapAllocation allow_allocation;
+ return CallJsBuiltin(isolate, "ArraySlice", args);
+ }
- len = Smi::cast(array->length())->value();
- } else {
- // Array.slice(arguments, ...) is quite a common idiom (notably more
- // than 50% of invocations in Web apps). Treat it in C++ as well.
- Handle<Map> arguments_map(isolate->context()->native_context()->
- sloppy_arguments_boilerplate()->map());
-
- bool is_arguments_object_with_fast_elements =
- receiver->IsJSObject() &&
- Handle<JSObject>::cast(receiver)->map() == *arguments_map;
- if (!is_arguments_object_with_fast_elements) {
- return CallJsBuiltin(isolate, "ArraySlice", args);
- }
- Handle<JSObject> object = Handle<JSObject>::cast(receiver);
+ if (!array->HasFastElements()) {
+ AllowHeapAllocation allow_allocation;
+ return CallJsBuiltin(isolate, "ArraySlice", args);
+ }
- if (object->HasFastElements()) {
- elms = handle(object->elements());
+ len = Smi::cast(array->length())->value();
} else {
- return CallJsBuiltin(isolate, "ArraySlice", args);
- }
- Handle<Object> len_obj(
- object->InObjectPropertyAt(Heap::kArgumentsLengthIndex), isolate);
- if (!len_obj->IsSmi()) {
- return CallJsBuiltin(isolate, "ArraySlice", args);
- }
- len = Handle<Smi>::cast(len_obj)->value();
- if (len > elms->length()) {
- return CallJsBuiltin(isolate, "ArraySlice", args);
- }
- }
-
- Handle<JSObject> object = Handle<JSObject>::cast(receiver);
+ // Array.slice(arguments, ...) is quite a common idiom (notably more
+ // than 50% of invocations in Web apps). Treat it in C++ as well.
+ Map* arguments_map = isolate->context()->native_context()->
+ sloppy_arguments_boilerplate()->map();
+
+ bool is_arguments_object_with_fast_elements =
+ receiver->IsJSObject() &&
+ JSObject::cast(*receiver)->map() == arguments_map;
+ if (!is_arguments_object_with_fast_elements) {
+ AllowHeapAllocation allow_allocation;
+ return CallJsBuiltin(isolate, "ArraySlice", args);
+ }
+ JSObject* object = JSObject::cast(*receiver);
- ASSERT(len >= 0);
- int n_arguments = args.length() - 1;
+ if (!object->HasFastElements()) {
+ AllowHeapAllocation allow_allocation;
+ return CallJsBuiltin(isolate, "ArraySlice", args);
+ }
- // Note carefully choosen defaults---if argument is missing,
- // it's undefined which gets converted to 0 for relative_start
- // and to len for relative_end.
- int relative_start = 0;
- int relative_end = len;
- if (n_arguments > 0) {
- Handle<Object> arg1 = args.at<Object>(1);
- if (arg1->IsSmi()) {
- relative_start = Handle<Smi>::cast(arg1)->value();
- } else if (arg1->IsHeapNumber()) {
- double start = Handle<HeapNumber>::cast(arg1)->value();
- if (start < kMinInt || start > kMaxInt) {
+ Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex);
+ if (!len_obj->IsSmi()) {
+ AllowHeapAllocation allow_allocation;
+ return CallJsBuiltin(isolate, "ArraySlice", args);
+ }
+ len = Smi::cast(len_obj)->value();
+ if (len > object->elements()->length()) {
+ AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySlice", args);
}
- relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
- } else if (!arg1->IsUndefined()) {
- return CallJsBuiltin(isolate, "ArraySlice", args);
}
- if (n_arguments > 1) {
- Handle<Object> arg2 = args.at<Object>(2);
- if (arg2->IsSmi()) {
- relative_end = Handle<Smi>::cast(arg2)->value();
- } else if (arg2->IsHeapNumber()) {
- double end = Handle<HeapNumber>::cast(arg2)->value();
- if (end < kMinInt || end > kMaxInt) {
+
+ ASSERT(len >= 0);
+ int n_arguments = args.length() - 1;
+
+ // Note carefully choosen defaults---if argument is missing,
+ // it's undefined which gets converted to 0 for relative_start
+ // and to len for relative_end.
+ relative_start = 0;
+ relative_end = len;
+ if (n_arguments > 0) {
+ Object* arg1 = args[1];
+ if (arg1->IsSmi()) {
+ relative_start = Smi::cast(arg1)->value();
+ } else if (arg1->IsHeapNumber()) {
+ double start = HeapNumber::cast(arg1)->value();
+ if (start < kMinInt || start > kMaxInt) {
+ AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySlice", args);
}
- relative_end = std::isnan(end) ? 0 : static_cast<int>(end);
- } else if (!arg2->IsUndefined()) {
+ relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
+ } else if (!arg1->IsUndefined()) {
+ AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySlice", args);
}
+ if (n_arguments > 1) {
+ Object* arg2 = args[2];
+ if (arg2->IsSmi()) {
+ relative_end = Smi::cast(arg2)->value();
+ } else if (arg2->IsHeapNumber()) {
+ double end = HeapNumber::cast(arg2)->value();
+ if (end < kMinInt || end > kMaxInt) {
+ AllowHeapAllocation allow_allocation;
+ return CallJsBuiltin(isolate, "ArraySlice", args);
+ }
+ relative_end = std::isnan(end) ? 0 : static_cast<int>(end);
+ } else if (!arg2->IsUndefined()) {
+ AllowHeapAllocation allow_allocation;
+ return CallJsBuiltin(isolate, "ArraySlice", args);
+ }
+ }
}
}
@@ -749,13 +729,16 @@ BUILTIN(ArraySlice) {
// Calculate the length of result array.
int result_len = Max(final - k, 0);
+ Handle<JSObject> object = Handle<JSObject>::cast(receiver);
+ Handle<FixedArrayBase> elms(object->elements(), isolate);
+
ElementsKind kind = object->GetElementsKind();
if (IsHoleyElementsKind(kind)) {
+ DisallowHeapAllocation no_gc;
bool packed = true;
ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
for (int i = k; i < final; i++) {
- if (!ElementsAccessorHasElementWrapper(
- accessor, object, object, i, elms)) {
+ if (!accessor->HasElement(object, object, i, elms)) {
packed = false;
break;
}
@@ -763,6 +746,7 @@ BUILTIN(ArraySlice) {
if (packed) {
kind = GetPackedElementsKind(kind);
} else if (!receiver->IsJSArray()) {
+ AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySlice", args);
}
}
@@ -774,8 +758,8 @@ BUILTIN(ArraySlice) {
if (result_len == 0) return *result_array;
ElementsAccessor* accessor = object->GetElementsAccessor();
- accessor->CopyElements(Handle<JSObject>::null(), k, kind,
- handle(result_array->elements()), 0, result_len, elms);
+ accessor->CopyElements(
+ elms, k, kind, handle(result_array->elements(), isolate), 0, result_len);
return *result_array;
}
@@ -784,9 +768,10 @@ BUILTIN(ArraySplice) {
HandleScope scope(isolate);
Heap* heap = isolate->heap();
Handle<Object> receiver = args.receiver();
- Handle<FixedArrayBase> elms_obj =
+ MaybeHandle<FixedArrayBase> maybe_elms_obj =
EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3);
- if (elms_obj.is_null() ||
+ Handle<FixedArrayBase> elms_obj;
+ if (!maybe_elms_obj.ToHandle(&elms_obj) ||
!IsJSArrayFastElementMovingAllowed(heap,
*Handle<JSArray>::cast(receiver))) {
return CallJsBuiltin(isolate, "ArraySplice", args);
@@ -800,16 +785,19 @@ BUILTIN(ArraySplice) {
int relative_start = 0;
if (n_arguments > 0) {
- Handle<Object> arg1 = args.at<Object>(1);
+ DisallowHeapAllocation no_gc;
+ Object* arg1 = args[1];
if (arg1->IsSmi()) {
- relative_start = Handle<Smi>::cast(arg1)->value();
+ relative_start = Smi::cast(arg1)->value();
} else if (arg1->IsHeapNumber()) {
- double start = Handle<HeapNumber>::cast(arg1)->value();
+ double start = HeapNumber::cast(arg1)->value();
if (start < kMinInt || start > kMaxInt) {
+ AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySplice", args);
}
relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
} else if (!arg1->IsUndefined()) {
+ AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySplice", args);
}
}
@@ -828,10 +816,12 @@ BUILTIN(ArraySplice) {
} else {
int value = 0; // ToInteger(undefined) == 0
if (n_arguments > 1) {
+ DisallowHeapAllocation no_gc;
Object* arg2 = args[2];
if (arg2->IsSmi()) {
value = Smi::cast(arg2)->value();
} else {
+ AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySplice", args);
}
}
@@ -865,8 +855,8 @@ BUILTIN(ArraySplice) {
DisallowHeapAllocation no_gc;
ElementsAccessor* accessor = array->GetElementsAccessor();
accessor->CopyElements(
- Handle<JSObject>::null(), actual_start, elements_kind,
- handle(result_array->elements()), 0, actual_delete_count, elms_obj);
+ elms_obj, actual_start, elements_kind,
+ handle(result_array->elements(), isolate), 0, actual_delete_count);
}
bool elms_changed = false;
@@ -890,7 +880,7 @@ BUILTIN(ArraySplice) {
if (heap->CanMoveObjectStart(*elms_obj)) {
// On the fast path we move the start of the object in memory.
- elms_obj = handle(LeftTrimFixedArray(heap, *elms_obj, delta));
+ elms_obj = handle(LeftTrimFixedArray(heap, *elms_obj, delta), isolate);
} else {
// This is the slow path. We are going to move the elements to the left
// by copying them. For trimmed values we store the hole.
@@ -898,12 +888,12 @@ BUILTIN(ArraySplice) {
Handle<FixedDoubleArray> elms =
Handle<FixedDoubleArray>::cast(elms_obj);
MoveDoubleElements(*elms, 0, *elms, delta, len - delta);
- FillWithHoles(*elms, len - delta, len);
+ elms->FillWithHoles(len - delta, len);
} else {
Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
DisallowHeapAllocation no_gc;
heap->MoveElements(*elms, 0, delta, len - delta);
- FillWithHoles(heap, *elms, len - delta, len);
+ elms->FillWithHoles(len - delta, len);
}
}
elms_changed = true;
@@ -914,14 +904,14 @@ BUILTIN(ArraySplice) {
MoveDoubleElements(*elms, actual_start + item_count,
*elms, actual_start + actual_delete_count,
(len - actual_delete_count - actual_start));
- FillWithHoles(*elms, new_length, len);
+ elms->FillWithHoles(new_length, len);
} else {
Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
DisallowHeapAllocation no_gc;
heap->MoveElements(*elms, actual_start + item_count,
actual_start + actual_delete_count,
(len - actual_delete_count - actual_start));
- FillWithHoles(heap, *elms, new_length, len);
+ elms->FillWithHoles(new_length, len);
}
}
} else if (item_count > actual_delete_count) {
@@ -944,12 +934,12 @@ BUILTIN(ArraySplice) {
if (actual_start > 0) {
// Copy the part before actual_start as is.
accessor->CopyElements(
- Handle<JSObject>::null(), 0, kind, new_elms, 0, actual_start, elms);
+ elms, 0, kind, new_elms, 0, actual_start);
}
accessor->CopyElements(
- Handle<JSObject>::null(), actual_start + actual_delete_count, kind,
+ elms, actual_start + actual_delete_count, kind,
new_elms, actual_start + item_count,
- ElementsAccessor::kCopyToEndAndInitializeToHole, elms);
+ ElementsAccessor::kCopyToEndAndInitializeToHole);
elms_obj = new_elms;
elms_changed = true;
@@ -992,51 +982,57 @@ BUILTIN(ArraySplice) {
BUILTIN(ArrayConcat) {
HandleScope scope(isolate);
- Heap* heap = isolate->heap();
- Handle<Context> native_context(isolate->context()->native_context());
- Handle<JSObject> array_proto(
- JSObject::cast(native_context->array_function()->prototype()));
- if (!ArrayPrototypeHasNoElements(heap, *native_context, *array_proto)) {
- return CallJsBuiltin(isolate, "ArrayConcat", args);
- }
- // Iterate through all the arguments performing checks
- // and calculating total length.
int n_arguments = args.length();
int result_len = 0;
ElementsKind elements_kind = GetInitialFastElementsKind();
bool has_double = false;
- bool is_holey = false;
- for (int i = 0; i < n_arguments; i++) {
- Handle<Object> arg = args.at<Object>(i);
- if (!arg->IsJSArray() ||
- !Handle<JSArray>::cast(arg)->HasFastElements() ||
- Handle<JSArray>::cast(arg)->GetPrototype() != *array_proto) {
+ {
+ DisallowHeapAllocation no_gc;
+ Heap* heap = isolate->heap();
+ Context* native_context = isolate->context()->native_context();
+ JSObject* array_proto =
+ JSObject::cast(native_context->array_function()->prototype());
+ if (!ArrayPrototypeHasNoElements(heap, native_context, array_proto)) {
+ AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArrayConcat", args);
}
- int len = Smi::cast(Handle<JSArray>::cast(arg)->length())->value();
-
- // We shouldn't overflow when adding another len.
- const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2);
- STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt);
- USE(kHalfOfMaxInt);
- result_len += len;
- ASSERT(result_len >= 0);
- if (result_len > FixedDoubleArray::kMaxLength) {
- return CallJsBuiltin(isolate, "ArrayConcat", args);
- }
+ // Iterate through all the arguments performing checks
+ // and calculating total length.
+ bool is_holey = false;
+ for (int i = 0; i < n_arguments; i++) {
+ Object* arg = args[i];
+ if (!arg->IsJSArray() ||
+ !JSArray::cast(arg)->HasFastElements() ||
+ JSArray::cast(arg)->GetPrototype() != array_proto) {
+ AllowHeapAllocation allow_allocation;
+ return CallJsBuiltin(isolate, "ArrayConcat", args);
+ }
+ int len = Smi::cast(JSArray::cast(arg)->length())->value();
+
+ // We shouldn't overflow when adding another len.
+ const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2);
+ STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt);
+ USE(kHalfOfMaxInt);
+ result_len += len;
+ ASSERT(result_len >= 0);
+
+ if (result_len > FixedDoubleArray::kMaxLength) {
+ AllowHeapAllocation allow_allocation;
+ return CallJsBuiltin(isolate, "ArrayConcat", args);
+ }
- ElementsKind arg_kind = Handle<JSArray>::cast(arg)->map()->elements_kind();
- has_double = has_double || IsFastDoubleElementsKind(arg_kind);
- is_holey = is_holey || IsFastHoleyElementsKind(arg_kind);
- if (IsMoreGeneralElementsKindTransition(elements_kind, arg_kind)) {
- elements_kind = arg_kind;
+ ElementsKind arg_kind = JSArray::cast(arg)->map()->elements_kind();
+ has_double = has_double || IsFastDoubleElementsKind(arg_kind);
+ is_holey = is_holey || IsFastHoleyElementsKind(arg_kind);
+ if (IsMoreGeneralElementsKindTransition(elements_kind, arg_kind)) {
+ elements_kind = arg_kind;
+ }
}
+ if (is_holey) elements_kind = GetHoleyElementsKind(elements_kind);
}
- if (is_holey) elements_kind = GetHoleyElementsKind(elements_kind);
-
// If a double array is concatted into a fast elements array, the fast
// elements array needs to be initialized to contain proper holes, since
// boxing doubles may cause incremental marking.
@@ -1051,10 +1047,12 @@ BUILTIN(ArrayConcat) {
if (result_len == 0) return *result_array;
int j = 0;
- Handle<FixedArrayBase> storage(result_array->elements());
+ Handle<FixedArrayBase> storage(result_array->elements(), isolate);
ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
for (int i = 0; i < n_arguments; i++) {
- Handle<JSArray> array = args.at<JSArray>(i);
+ // TODO(ishell): It is crucial to keep |array| as a raw pointer to avoid
+ // performance degradation. Revisit this later.
+ JSArray* array = JSArray::cast(args[i]);
int len = Smi::cast(array->length())->value();
ElementsKind from_kind = array->GetElementsKind();
if (len > 0) {
@@ -1143,7 +1141,7 @@ static inline Object* TypeCheck(Heap* heap,
template <bool is_construct>
-MUST_USE_RESULT static MaybeObject* HandleApiCallHelper(
+MUST_USE_RESULT static Object* HandleApiCallHelper(
BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) {
ASSERT(is_construct == CalledAsConstructor(isolate));
Heap* heap = isolate->heap();
@@ -1152,15 +1150,13 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallHelper(
Handle<JSFunction> function = args.called_function();
ASSERT(function->shared()->IsApiFunction());
- FunctionTemplateInfo* fun_data = function->shared()->get_api_func_data();
+ Handle<FunctionTemplateInfo> fun_data(
+ function->shared()->get_api_func_data(), isolate);
if (is_construct) {
- Handle<FunctionTemplateInfo> desc(fun_data, isolate);
- bool pending_exception = false;
- isolate->factory()->ConfigureInstance(
- desc, Handle<JSObject>::cast(args.receiver()), &pending_exception);
- ASSERT(isolate->has_pending_exception() == pending_exception);
- if (pending_exception) return Failure::Exception();
- fun_data = *desc;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, fun_data,
+ isolate->factory()->ConfigureInstance(
+ fun_data, Handle<JSObject>::cast(args.receiver())));
}
SharedFunctionInfo* shared = function->shared();
@@ -1172,7 +1168,7 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallHelper(
}
}
- Object* raw_holder = TypeCheck(heap, args.length(), &args[0], fun_data);
+ Object* raw_holder = TypeCheck(heap, args.length(), &args[0], *fun_data);
if (raw_holder->IsNull()) {
// This function cannot be called with the given receiver. Abort!
@@ -1210,7 +1206,7 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallHelper(
result->VerifyApiCallResultType();
}
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
if (!is_construct || result->IsJSObject()) return result;
}
@@ -1231,7 +1227,7 @@ BUILTIN(HandleApiCallConstruct) {
// Helper function to handle calls to non-function objects created through the
// API. The object can be called as either a constructor (using new) or just as
// a function (without new).
-MUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor(
+MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor(
Isolate* isolate,
bool is_construct_call,
BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
@@ -1280,7 +1276,7 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor(
}
}
// Check for exceptions and return result.
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return result;
}
@@ -1424,7 +1420,11 @@ static void Generate_KeyedStoreIC_SloppyArguments(MacroAssembler* masm) {
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
+static void Generate_CallICStub_DebugBreak(MacroAssembler* masm) {
+ Debug::GenerateCallICStubDebugBreak(masm);
+}
+
+
static void Generate_LoadIC_DebugBreak(MacroAssembler* masm) {
Debug::GenerateLoadICDebugBreak(masm);
}
@@ -1460,12 +1460,6 @@ static void Generate_CallFunctionStub_DebugBreak(MacroAssembler* masm) {
}
-static void Generate_CallFunctionStub_Recording_DebugBreak(
- MacroAssembler* masm) {
- Debug::GenerateCallFunctionStubRecordDebugBreak(masm);
-}
-
-
static void Generate_CallConstructStub_DebugBreak(MacroAssembler* masm) {
Debug::GenerateCallConstructStubDebugBreak(masm);
}
@@ -1490,7 +1484,6 @@ static void Generate_PlainReturn_LiveEdit(MacroAssembler* masm) {
static void Generate_FrameDropper_LiveEdit(MacroAssembler* masm) {
Debug::GenerateFrameDropperLiveEdit(masm);
}
-#endif
Builtins::Builtins() : initialized_(false) {
@@ -1602,7 +1595,6 @@ void Builtins::InitBuiltinFunctionTable() {
void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) {
ASSERT(!initialized_);
- Heap* heap = isolate->heap();
// Create a scope for the handles in the builtins.
HandleScope scope(isolate);
@@ -1633,32 +1625,18 @@ void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) {
CodeDesc desc;
masm.GetCode(&desc);
Code::Flags flags = functions[i].flags;
- Object* code = NULL;
- {
- // During startup it's OK to always allocate and defer GC to later.
- // This simplifies things because we don't need to retry.
- AlwaysAllocateScope __scope__(isolate);
- { MaybeObject* maybe_code =
- heap->CreateCode(desc, flags, masm.CodeObject());
- if (!maybe_code->ToObject(&code)) {
- v8::internal::V8::FatalProcessOutOfMemory("CreateCode");
- }
- }
- }
+ Handle<Code> code =
+ isolate->factory()->NewCode(desc, flags, masm.CodeObject());
// Log the event and add the code to the builtins array.
PROFILE(isolate,
- CodeCreateEvent(Logger::BUILTIN_TAG,
- Code::cast(code),
- functions[i].s_name));
- GDBJIT(AddCode(GDBJITInterface::BUILTIN,
- functions[i].s_name,
- Code::cast(code)));
- builtins_[i] = code;
+ CodeCreateEvent(Logger::BUILTIN_TAG, *code, functions[i].s_name));
+ GDBJIT(AddCode(GDBJITInterface::BUILTIN, functions[i].s_name, *code));
+ builtins_[i] = *code;
#ifdef ENABLE_DISASSEMBLER
if (FLAG_print_builtin_code) {
CodeTracer::Scope trace_scope(isolate->GetCodeTracer());
PrintF(trace_scope.file(), "Builtin: %s\n", functions[i].s_name);
- Code::cast(code)->Disassemble(functions[i].s_name, trace_scope.file());
+ code->Disassemble(functions[i].s_name, trace_scope.file());
PrintF(trace_scope.file(), "\n");
}
#endif
diff --git a/deps/v8/src/builtins.h b/deps/v8/src/builtins.h
index 88cfd53f48..e6b60c732c 100644
--- a/deps/v8/src/builtins.h
+++ b/deps/v8/src/builtins.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_BUILTINS_H_
#define V8_BUILTINS_H_
@@ -197,19 +174,18 @@ enum BuiltinExtraArguments {
V(LoadIC_Normal, LOAD_IC) \
V(StoreIC_Normal, STORE_IC)
-#ifdef ENABLE_DEBUGGER_SUPPORT
// Define list of builtins used by the debugger implemented in assembly.
#define BUILTIN_LIST_DEBUG_A(V) \
V(Return_DebugBreak, BUILTIN, DEBUG_STUB, \
DEBUG_BREAK) \
V(CallFunctionStub_DebugBreak, BUILTIN, DEBUG_STUB, \
DEBUG_BREAK) \
- V(CallFunctionStub_Recording_DebugBreak, BUILTIN, DEBUG_STUB, \
- DEBUG_BREAK) \
V(CallConstructStub_DebugBreak, BUILTIN, DEBUG_STUB, \
DEBUG_BREAK) \
V(CallConstructStub_Recording_DebugBreak, BUILTIN, DEBUG_STUB, \
DEBUG_BREAK) \
+ V(CallICStub_DebugBreak, CALL_IC, DEBUG_STUB, \
+ DEBUG_BREAK) \
V(LoadIC_DebugBreak, LOAD_IC, DEBUG_STUB, \
DEBUG_BREAK) \
V(KeyedLoadIC_DebugBreak, KEYED_LOAD_IC, DEBUG_STUB, \
@@ -226,9 +202,6 @@ enum BuiltinExtraArguments {
DEBUG_BREAK) \
V(FrameDropper_LiveEdit, BUILTIN, DEBUG_STUB, \
DEBUG_BREAK)
-#else
-#define BUILTIN_LIST_DEBUG_A(V)
-#endif
// Define list of builtins implemented in JavaScript.
#define BUILTINS_LIST_JS(V) \
@@ -260,7 +233,7 @@ enum BuiltinExtraArguments {
V(STRING_ADD_LEFT, 1) \
V(STRING_ADD_RIGHT, 1) \
V(APPLY_PREPARE, 1) \
- V(APPLY_OVERFLOW, 1)
+ V(STACK_OVERFLOW, 1)
class BuiltinFunctionTable;
class ObjectVisitor;
diff --git a/deps/v8/src/bytecodes-irregexp.h b/deps/v8/src/bytecodes-irregexp.h
index c7cc66e527..04b9740acb 100644
--- a/deps/v8/src/bytecodes-irregexp.h
+++ b/deps/v8/src/bytecodes-irregexp.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_BYTECODES_IRREGEXP_H_
diff --git a/deps/v8/src/cached-powers.cc b/deps/v8/src/cached-powers.cc
index faa26cdba2..8a00968482 100644
--- a/deps/v8/src/cached-powers.cc
+++ b/deps/v8/src/cached-powers.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <stdarg.h>
#include <limits.h>
diff --git a/deps/v8/src/cached-powers.h b/deps/v8/src/cached-powers.h
index 88df22260c..b58924fb36 100644
--- a/deps/v8/src/cached-powers.h
+++ b/deps/v8/src/cached-powers.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_CACHED_POWERS_H_
#define V8_CACHED_POWERS_H_
diff --git a/deps/v8/src/char-predicates-inl.h b/deps/v8/src/char-predicates-inl.h
index dee9ccd381..16a89f4c3d 100644
--- a/deps/v8/src/char-predicates-inl.h
+++ b/deps/v8/src/char-predicates-inl.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_CHAR_PREDICATES_INL_H_
#define V8_CHAR_PREDICATES_INL_H_
diff --git a/deps/v8/src/char-predicates.h b/deps/v8/src/char-predicates.h
index f52feda6c1..84247e43ce 100644
--- a/deps/v8/src/char-predicates.h
+++ b/deps/v8/src/char-predicates.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_CHAR_PREDICATES_H_
#define V8_CHAR_PREDICATES_H_
diff --git a/deps/v8/src/checks.cc b/deps/v8/src/checks.cc
index 3a2de28a2e..4667facad8 100644
--- a/deps/v8/src/checks.cc
+++ b/deps/v8/src/checks.cc
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "checks.h"
@@ -98,8 +75,6 @@ void DumpBacktrace() {
// Contains protection against recursive calls (faults while handling faults).
extern "C" void V8_Fatal(const char* file, int line, const char* format, ...) {
- i::AllowHandleDereference allow_deref;
- i::AllowDeferredHandleDereference allow_deferred_deref;
fflush(stdout);
fflush(stderr);
i::OS::PrintError("\n\n#\n# Fatal error in %s, line %d\n# ", file, line);
diff --git a/deps/v8/src/checks.h b/deps/v8/src/checks.h
index e53475a0a4..c2ccc8193e 100644
--- a/deps/v8/src/checks.h
+++ b/deps/v8/src/checks.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_CHECKS_H_
#define V8_CHECKS_H_
diff --git a/deps/v8/src/circular-queue-inl.h b/deps/v8/src/circular-queue-inl.h
index dfb7031578..14910a17e4 100644
--- a/deps/v8/src/circular-queue-inl.h
+++ b/deps/v8/src/circular-queue-inl.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_CIRCULAR_QUEUE_INL_H_
#define V8_CIRCULAR_QUEUE_INL_H_
diff --git a/deps/v8/src/circular-queue.h b/deps/v8/src/circular-queue.h
index 71ef38322f..81e80d2aa4 100644
--- a/deps/v8/src/circular-queue.h
+++ b/deps/v8/src/circular-queue.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_CIRCULAR_QUEUE_H_
#define V8_CIRCULAR_QUEUE_H_
diff --git a/deps/v8/src/code-stubs-hydrogen.cc b/deps/v8/src/code-stubs-hydrogen.cc
index 040c260133..68c864176b 100644
--- a/deps/v8/src/code-stubs-hydrogen.cc
+++ b/deps/v8/src/code-stubs-hydrogen.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -60,7 +37,7 @@ class CodeStubGraphBuilderBase : public HGraphBuilder {
arguments_length_(NULL),
info_(stub, isolate),
context_(NULL) {
- descriptor_ = stub->GetInterfaceDescriptor(isolate);
+ descriptor_ = stub->GetInterfaceDescriptor();
parameters_.Reset(new HParameter*[descriptor_->register_param_count_]);
}
virtual bool BuildGraph();
@@ -238,15 +215,15 @@ class CodeStubGraphBuilder: public CodeStubGraphBuilderBase {
};
-Handle<Code> HydrogenCodeStub::GenerateLightweightMissCode(Isolate* isolate) {
- Factory* factory = isolate->factory();
+Handle<Code> HydrogenCodeStub::GenerateLightweightMissCode() {
+ Factory* factory = isolate()->factory();
// Generate the new code.
- MacroAssembler masm(isolate, NULL, 256);
+ MacroAssembler masm(isolate(), NULL, 256);
{
// Update the static counter each time a new code stub is generated.
- isolate->counters()->code_stubs()->Increment();
+ isolate()->counters()->code_stubs()->Increment();
// Generate the code for the stub.
masm.set_generating_stub(true);
@@ -271,13 +248,14 @@ Handle<Code> HydrogenCodeStub::GenerateLightweightMissCode(Isolate* isolate) {
template <class Stub>
-static Handle<Code> DoGenerateCode(Isolate* isolate, Stub* stub) {
+static Handle<Code> DoGenerateCode(Stub* stub) {
+ Isolate* isolate = stub->isolate();
CodeStub::Major major_key =
static_cast<HydrogenCodeStub*>(stub)->MajorKey();
CodeStubInterfaceDescriptor* descriptor =
isolate->code_stub_interface_descriptor(major_key);
if (descriptor->register_param_count_ < 0) {
- stub->InitializeInterfaceDescriptor(isolate, descriptor);
+ stub->InitializeInterfaceDescriptor(descriptor);
}
// If we are uninitialized we can use a light-weight stub to enter
@@ -285,7 +263,7 @@ static Handle<Code> DoGenerateCode(Isolate* isolate, Stub* stub) {
// stub-failure deopt mechanism.
if (stub->IsUninitialized() && descriptor->has_miss_handler()) {
ASSERT(!descriptor->stack_parameter_count_.is_valid());
- return stub->GenerateLightweightMissCode(isolate);
+ return stub->GenerateLightweightMissCode();
}
ElapsedTimer timer;
if (FLAG_profile_hydrogen_code_stub_compilation) {
@@ -329,8 +307,8 @@ HValue* CodeStubGraphBuilder<ToNumberStub>::BuildCodeStub() {
}
-Handle<Code> ToNumberStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> ToNumberStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -342,8 +320,8 @@ HValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() {
}
-Handle<Code> NumberToStringStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> NumberToStringStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -416,8 +394,8 @@ HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() {
}
-Handle<Code> FastCloneShallowArrayStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> FastCloneShallowArrayStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -483,8 +461,8 @@ HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
}
-Handle<Code> FastCloneShallowObjectStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> FastCloneShallowObjectStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -553,8 +531,8 @@ HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() {
}
-Handle<Code> CreateAllocationSiteStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> CreateAllocationSiteStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -568,8 +546,8 @@ HValue* CodeStubGraphBuilder<KeyedLoadFastElementStub>::BuildCodeStub() {
}
-Handle<Code> KeyedLoadFastElementStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> KeyedLoadFastElementStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -602,8 +580,8 @@ HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() {
}
-Handle<Code> LoadFieldStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> LoadFieldStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -616,8 +594,8 @@ HValue* CodeStubGraphBuilder<StringLengthStub>::BuildCodeStub() {
}
-Handle<Code> StringLengthStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> StringLengthStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -632,8 +610,8 @@ HValue* CodeStubGraphBuilder<KeyedStoreFastElementStub>::BuildCodeStub() {
}
-Handle<Code> KeyedStoreFastElementStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> KeyedStoreFastElementStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -651,8 +629,8 @@ HValue* CodeStubGraphBuilder<TransitionElementsKindStub>::BuildCodeStub() {
}
-Handle<Code> TransitionElementsKindStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> TransitionElementsKindStub::GenerateCode() {
+ return DoGenerateCode(this);
}
HValue* CodeStubGraphBuilderBase::BuildArrayConstructor(
@@ -768,8 +746,8 @@ HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() {
}
-Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -782,9 +760,8 @@ HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>::
}
-Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode(
- Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -796,8 +773,8 @@ HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() {
}
-Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -809,9 +786,8 @@ HValue* CodeStubGraphBuilder<InternalArrayNoArgumentConstructorStub>::
}
-Handle<Code> InternalArrayNoArgumentConstructorStub::GenerateCode(
- Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> InternalArrayNoArgumentConstructorStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -823,9 +799,8 @@ HValue* CodeStubGraphBuilder<InternalArraySingleArgumentConstructorStub>::
}
-Handle<Code> InternalArraySingleArgumentConstructorStub::GenerateCode(
- Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> InternalArraySingleArgumentConstructorStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -837,9 +812,8 @@ HValue* CodeStubGraphBuilder<InternalArrayNArgumentsConstructorStub>::
}
-Handle<Code> InternalArrayNArgumentsConstructorStub::GenerateCode(
- Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> InternalArrayNArgumentsConstructorStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -864,8 +838,8 @@ HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeInitializedStub() {
}
-Handle<Code> CompareNilICStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> CompareNilICStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -963,7 +937,7 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
if (state.CanReuseDoubleBox()) {
HValue* operand = (state.mode() == OVERWRITE_LEFT) ? left : right;
IfBuilder if_heap_number(this);
- if_heap_number.IfNot<HIsSmiAndBranch>(operand);
+ if_heap_number.If<HHasInstanceTypeAndBranch>(operand, HEAP_NUMBER_TYPE);
if_heap_number.Then();
Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result);
Push(operand);
@@ -977,8 +951,8 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
}
-Handle<Code> BinaryOpICStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> BinaryOpICStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -1002,8 +976,8 @@ HValue* CodeStubGraphBuilder<BinaryOpWithAllocationSiteStub>::BuildCodeStub() {
}
-Handle<Code> BinaryOpWithAllocationSiteStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> BinaryOpWithAllocationSiteStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -1028,8 +1002,8 @@ HValue* CodeStubGraphBuilder<StringAddStub>::BuildCodeInitializedStub() {
}
-Handle<Code> StringAddStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> StringAddStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -1047,8 +1021,8 @@ HValue* CodeStubGraphBuilder<ToBooleanStub>::BuildCodeInitializedStub() {
}
-Handle<Code> ToBooleanStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> ToBooleanStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -1068,7 +1042,7 @@ HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() {
Handle<Map> placeholder_map = isolate()->factory()->meta_map();
HValue* global = Add<HConstant>(
StoreGlobalStub::global_placeholder(isolate()));
- Add<HCheckMaps>(global, placeholder_map, top_info());
+ Add<HCheckMaps>(global, placeholder_map);
}
HValue* cell = Add<HConstant>(placeholder_cell);
@@ -1100,8 +1074,8 @@ HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() {
}
-Handle<Code> StoreGlobalStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> StoreGlobalStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -1134,8 +1108,8 @@ HValue* CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() {
}
-Handle<Code> ElementsTransitionAndStoreStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -1344,8 +1318,8 @@ HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() {
}
-Handle<Code> FastNewClosureStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> FastNewClosureStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -1399,8 +1373,8 @@ HValue* CodeStubGraphBuilder<FastNewContextStub>::BuildCodeStub() {
}
-Handle<Code> FastNewContextStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> FastNewContextStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -1415,8 +1389,8 @@ HValue* CodeStubGraphBuilder<KeyedLoadDictionaryElementStub>::BuildCodeStub() {
}
-Handle<Code> KeyedLoadDictionaryElementStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> KeyedLoadDictionaryElementStub::GenerateCode() {
+ return DoGenerateCode(this);
}
@@ -1431,8 +1405,8 @@ HValue* CodeStubGraphBuilder<RegExpConstructResultStub>::BuildCodeStub() {
}
-Handle<Code> RegExpConstructResultStub::GenerateCode(Isolate* isolate) {
- return DoGenerateCode(isolate, this);
+Handle<Code> RegExpConstructResultStub::GenerateCode() {
+ return DoGenerateCode(this);
}
diff --git a/deps/v8/src/code-stubs.cc b/deps/v8/src/code-stubs.cc
index 06203629ae..24f60ed412 100644
--- a/deps/v8/src/code-stubs.cc
+++ b/deps/v8/src/code-stubs.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -51,8 +28,8 @@ CodeStubInterfaceDescriptor::CodeStubInterfaceDescriptor()
has_miss_handler_(false) { }
-bool CodeStub::FindCodeInCache(Code** code_out, Isolate* isolate) {
- UnseededNumberDictionary* stubs = isolate->heap()->code_stubs();
+bool CodeStub::FindCodeInCache(Code** code_out) {
+ UnseededNumberDictionary* stubs = isolate()->heap()->code_stubs();
int index = stubs->FindEntry(GetKey());
if (index != UnseededNumberDictionary::kNotFound) {
*code_out = Code::cast(stubs->ValueAt(index));
@@ -72,11 +49,12 @@ SmartArrayPointer<const char> CodeStub::GetName() {
}
-void CodeStub::RecordCodeGeneration(Code* code, Isolate* isolate) {
+void CodeStub::RecordCodeGeneration(Handle<Code> code) {
+ IC::RegisterWeakMapDependency(code);
SmartArrayPointer<const char> name = GetName();
- PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, name.get()));
- GDBJIT(AddCode(GDBJITInterface::STUB, name.get(), code));
- Counters* counters = isolate->counters();
+ PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, name.get()));
+ GDBJIT(AddCode(GDBJITInterface::STUB, name.get(), *code));
+ Counters* counters = isolate()->counters();
counters->total_stubs_code_size()->Increment(code->instruction_size());
}
@@ -86,25 +64,24 @@ Code::Kind CodeStub::GetCodeKind() const {
}
-Handle<Code> CodeStub::GetCodeCopy(Isolate* isolate,
- const Code::FindAndReplacePattern& pattern) {
- Handle<Code> ic = GetCode(isolate);
- ic = isolate->factory()->CopyCode(ic);
+Handle<Code> CodeStub::GetCodeCopy(const Code::FindAndReplacePattern& pattern) {
+ Handle<Code> ic = GetCode();
+ ic = isolate()->factory()->CopyCode(ic);
ic->FindAndReplace(pattern);
- RecordCodeGeneration(*ic, isolate);
+ RecordCodeGeneration(ic);
return ic;
}
-Handle<Code> PlatformCodeStub::GenerateCode(Isolate* isolate) {
- Factory* factory = isolate->factory();
+Handle<Code> PlatformCodeStub::GenerateCode() {
+ Factory* factory = isolate()->factory();
// Generate the new code.
- MacroAssembler masm(isolate, NULL, 256);
+ MacroAssembler masm(isolate(), NULL, 256);
{
// Update the static counter each time a new code stub is generated.
- isolate->counters()->code_stubs()->Increment();
+ isolate()->counters()->code_stubs()->Increment();
// Generate the code for the stub.
masm.set_generating_stub(true);
@@ -128,37 +105,36 @@ Handle<Code> PlatformCodeStub::GenerateCode(Isolate* isolate) {
}
-void CodeStub::VerifyPlatformFeatures(Isolate* isolate) {
+void CodeStub::VerifyPlatformFeatures() {
ASSERT(CpuFeatures::VerifyCrossCompiling());
}
-Handle<Code> CodeStub::GetCode(Isolate* isolate) {
- Factory* factory = isolate->factory();
- Heap* heap = isolate->heap();
+Handle<Code> CodeStub::GetCode() {
+ Heap* heap = isolate()->heap();
Code* code;
if (UseSpecialCache()
- ? FindCodeInSpecialCache(&code, isolate)
- : FindCodeInCache(&code, isolate)) {
+ ? FindCodeInSpecialCache(&code)
+ : FindCodeInCache(&code)) {
ASSERT(GetCodeKind() == code->kind());
return Handle<Code>(code);
}
#ifdef DEBUG
- VerifyPlatformFeatures(isolate);
+ VerifyPlatformFeatures();
#endif
{
- HandleScope scope(isolate);
+ HandleScope scope(isolate());
- Handle<Code> new_object = GenerateCode(isolate);
+ Handle<Code> new_object = GenerateCode();
new_object->set_major_key(MajorKey());
FinishCode(new_object);
- RecordCodeGeneration(*new_object, isolate);
+ RecordCodeGeneration(new_object);
#ifdef ENABLE_DISASSEMBLER
if (FLAG_print_code_stubs) {
- CodeTracer::Scope trace_scope(isolate->GetCodeTracer());
+ CodeTracer::Scope trace_scope(isolate()->GetCodeTracer());
new_object->Disassemble(GetName().get(), trace_scope.file());
PrintF(trace_scope.file(), "\n");
}
@@ -169,7 +145,7 @@ Handle<Code> CodeStub::GetCode(Isolate* isolate) {
} else {
// Update the dictionary and the root in Heap.
Handle<UnseededNumberDictionary> dict =
- factory->DictionaryAtNumberPut(
+ UnseededNumberDictionary::AtNumberPut(
Handle<UnseededNumberDictionary>(heap->code_stubs()),
GetKey(),
new_object);
@@ -182,7 +158,7 @@ Handle<Code> CodeStub::GetCode(Isolate* isolate) {
ASSERT(!NeedsImmovableCode() ||
heap->lo_space()->Contains(code) ||
heap->code_space()->FirstPage()->Contains(code->address()));
- return Handle<Code>(code, isolate);
+ return Handle<Code>(code, isolate());
}
@@ -218,9 +194,10 @@ void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate) {
// Generate the uninitialized versions of the stub.
for (int op = Token::BIT_OR; op <= Token::MOD; ++op) {
for (int mode = NO_OVERWRITE; mode <= OVERWRITE_RIGHT; ++mode) {
- BinaryOpICStub stub(static_cast<Token::Value>(op),
+ BinaryOpICStub stub(isolate,
+ static_cast<Token::Value>(op),
static_cast<OverwriteMode>(mode));
- stub.GetCode(isolate);
+ stub.GetCode();
}
}
@@ -237,8 +214,8 @@ void BinaryOpICStub::PrintState(StringStream* stream) {
// static
void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate,
const BinaryOpIC::State& state) {
- BinaryOpICStub stub(state);
- stub.GetCode(isolate);
+ BinaryOpICStub stub(isolate, state);
+ stub.GetCode();
}
@@ -258,8 +235,8 @@ void BinaryOpICWithAllocationSiteStub::PrintState(StringStream* stream) {
void BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(
Isolate* isolate, const BinaryOpIC::State& state) {
if (state.CouldCreateAllocationMementos()) {
- BinaryOpICWithAllocationSiteStub stub(state);
- stub.GetCode(isolate);
+ BinaryOpICWithAllocationSiteStub stub(isolate, state);
+ stub.GetCode();
}
}
@@ -312,8 +289,8 @@ void ICCompareStub::AddToSpecialCache(Handle<Code> new_object) {
}
-bool ICCompareStub::FindCodeInSpecialCache(Code** code_out, Isolate* isolate) {
- Factory* factory = isolate->factory();
+bool ICCompareStub::FindCodeInSpecialCache(Code** code_out) {
+ Factory* factory = isolate()->factory();
Code::Flags flags = Code::ComputeFlags(
GetCodeKind(),
UNINITIALIZED);
@@ -324,7 +301,7 @@ bool ICCompareStub::FindCodeInSpecialCache(Code** code_out, Isolate* isolate) {
*factory->strict_compare_ic_string() :
*factory->compare_ic_string(),
flags),
- isolate);
+ isolate());
if (probe->IsCode()) {
*code_out = Code::cast(*probe);
#ifdef DEBUG
@@ -501,6 +478,11 @@ Type* CompareNilICStub::GetInputType(Zone* zone, Handle<Map> map) {
}
+void CallICStub::PrintState(StringStream* stream) {
+ state_.Print(stream);
+}
+
+
void InstanceofStub::PrintName(StringStream* stream) {
const char* args = "";
if (HasArgsInRegisters()) {
@@ -539,8 +521,8 @@ void KeyedLoadDictionaryElementPlatformStub::Generate(
void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
- CreateAllocationSiteStub stub;
- stub.GetCode(isolate);
+ CreateAllocationSiteStub stub(isolate);
+ stub.GetCode();
}
@@ -583,7 +565,6 @@ void ArgumentsAccessStub::PrintName(StringStream* stream) {
void CallFunctionStub::PrintName(StringStream* stream) {
stream->Add("CallFunctionStub_Args%d", argc_);
- if (RecordCallTarget()) stream->Add("_Recording");
}
@@ -695,10 +676,10 @@ bool ToBooleanStub::Types::CanBeUndetectable() const {
void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) {
- StubFailureTrampolineStub stub1(NOT_JS_FUNCTION_STUB_MODE);
- StubFailureTrampolineStub stub2(JS_FUNCTION_STUB_MODE);
- stub1.GetCode(isolate);
- stub2.GetCode(isolate);
+ StubFailureTrampolineStub stub1(isolate, NOT_JS_FUNCTION_STUB_MODE);
+ StubFailureTrampolineStub stub2(isolate, JS_FUNCTION_STUB_MODE);
+ stub1.GetCode();
+ stub2.GetCode();
}
@@ -716,42 +697,44 @@ static void InstallDescriptor(Isolate* isolate, HydrogenCodeStub* stub) {
CodeStubInterfaceDescriptor* descriptor =
isolate->code_stub_interface_descriptor(major_key);
if (!descriptor->initialized()) {
- stub->InitializeInterfaceDescriptor(isolate, descriptor);
+ stub->InitializeInterfaceDescriptor(descriptor);
}
}
void ArrayConstructorStubBase::InstallDescriptors(Isolate* isolate) {
- ArrayNoArgumentConstructorStub stub1(GetInitialFastElementsKind());
+ ArrayNoArgumentConstructorStub stub1(isolate, GetInitialFastElementsKind());
InstallDescriptor(isolate, &stub1);
- ArraySingleArgumentConstructorStub stub2(GetInitialFastElementsKind());
+ ArraySingleArgumentConstructorStub stub2(isolate,
+ GetInitialFastElementsKind());
InstallDescriptor(isolate, &stub2);
- ArrayNArgumentsConstructorStub stub3(GetInitialFastElementsKind());
+ ArrayNArgumentsConstructorStub stub3(isolate, GetInitialFastElementsKind());
InstallDescriptor(isolate, &stub3);
}
void NumberToStringStub::InstallDescriptors(Isolate* isolate) {
- NumberToStringStub stub;
+ NumberToStringStub stub(isolate);
InstallDescriptor(isolate, &stub);
}
void FastNewClosureStub::InstallDescriptors(Isolate* isolate) {
- FastNewClosureStub stub(STRICT, false);
+ FastNewClosureStub stub(isolate, STRICT, false);
InstallDescriptor(isolate, &stub);
}
void FastNewContextStub::InstallDescriptors(Isolate* isolate) {
- FastNewContextStub stub(FastNewContextStub::kMaximumSlots);
+ FastNewContextStub stub(isolate, FastNewContextStub::kMaximumSlots);
InstallDescriptor(isolate, &stub);
}
// static
void FastCloneShallowArrayStub::InstallDescriptors(Isolate* isolate) {
- FastCloneShallowArrayStub stub(FastCloneShallowArrayStub::CLONE_ELEMENTS,
+ FastCloneShallowArrayStub stub(isolate,
+ FastCloneShallowArrayStub::CLONE_ELEMENTS,
DONT_TRACK_ALLOCATION_SITE, 0);
InstallDescriptor(isolate, &stub);
}
@@ -759,40 +742,41 @@ void FastCloneShallowArrayStub::InstallDescriptors(Isolate* isolate) {
// static
void BinaryOpICStub::InstallDescriptors(Isolate* isolate) {
- BinaryOpICStub stub(Token::ADD, NO_OVERWRITE);
+ BinaryOpICStub stub(isolate, Token::ADD, NO_OVERWRITE);
InstallDescriptor(isolate, &stub);
}
// static
void BinaryOpWithAllocationSiteStub::InstallDescriptors(Isolate* isolate) {
- BinaryOpWithAllocationSiteStub stub(Token::ADD, NO_OVERWRITE);
+ BinaryOpWithAllocationSiteStub stub(isolate, Token::ADD, NO_OVERWRITE);
InstallDescriptor(isolate, &stub);
}
// static
void StringAddStub::InstallDescriptors(Isolate* isolate) {
- StringAddStub stub(STRING_ADD_CHECK_NONE, NOT_TENURED);
+ StringAddStub stub(isolate, STRING_ADD_CHECK_NONE, NOT_TENURED);
InstallDescriptor(isolate, &stub);
}
// static
void RegExpConstructResultStub::InstallDescriptors(Isolate* isolate) {
- RegExpConstructResultStub stub;
+ RegExpConstructResultStub stub(isolate);
InstallDescriptor(isolate, &stub);
}
ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate)
- : argument_count_(ANY) {
+ : PlatformCodeStub(isolate), argument_count_(ANY) {
ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
}
ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate,
- int argument_count) {
+ int argument_count)
+ : PlatformCodeStub(isolate) {
if (argument_count == 0) {
argument_count_ = NONE;
} else if (argument_count == 1) {
@@ -807,16 +791,16 @@ ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate,
void InternalArrayConstructorStubBase::InstallDescriptors(Isolate* isolate) {
- InternalArrayNoArgumentConstructorStub stub1(FAST_ELEMENTS);
+ InternalArrayNoArgumentConstructorStub stub1(isolate, FAST_ELEMENTS);
InstallDescriptor(isolate, &stub1);
- InternalArraySingleArgumentConstructorStub stub2(FAST_ELEMENTS);
+ InternalArraySingleArgumentConstructorStub stub2(isolate, FAST_ELEMENTS);
InstallDescriptor(isolate, &stub2);
- InternalArrayNArgumentsConstructorStub stub3(FAST_ELEMENTS);
+ InternalArrayNArgumentsConstructorStub stub3(isolate, FAST_ELEMENTS);
InstallDescriptor(isolate, &stub3);
}
InternalArrayConstructorStub::InternalArrayConstructorStub(
- Isolate* isolate) {
+ Isolate* isolate) : PlatformCodeStub(isolate) {
InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
}
diff --git a/deps/v8/src/code-stubs.h b/deps/v8/src/code-stubs.h
index 5a88942330..8380266d92 100644
--- a/deps/v8/src/code-stubs.h
+++ b/deps/v8/src/code-stubs.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_CODE_STUBS_H_
#define V8_CODE_STUBS_H_
@@ -51,6 +28,7 @@ namespace internal {
V(CompareIC) \
V(CompareNilIC) \
V(MathPow) \
+ V(CallIC) \
V(FunctionPrototype) \
V(RecordWrite) \
V(StoreBufferOverflow) \
@@ -74,7 +52,6 @@ namespace internal {
V(CEntry) \
V(JSEntry) \
V(KeyedLoadElement) \
- V(ArrayPush) \
V(ArrayNoArgumentConstructor) \
V(ArraySingleArgumentConstructor) \
V(ArrayNArgumentsConstructor) \
@@ -155,11 +132,10 @@ class CodeStub BASE_EMBEDDED {
};
// Retrieve the code for the stub. Generate the code if needed.
- Handle<Code> GetCode(Isolate* isolate);
+ Handle<Code> GetCode();
// Retrieve the code for the stub, make and return a copy of the code.
- Handle<Code> GetCodeCopy(
- Isolate* isolate, const Code::FindAndReplacePattern& pattern);
+ Handle<Code> GetCodeCopy(const Code::FindAndReplacePattern& pattern);
static Major MajorKeyFromKey(uint32_t key) {
return static_cast<Major>(MajorKeyBits::decode(key));
@@ -175,6 +151,7 @@ class CodeStub BASE_EMBEDDED {
static const char* MajorName(Major major_key, bool allow_unknown_keys);
+ explicit CodeStub(Isolate* isolate) : isolate_(isolate) { }
virtual ~CodeStub() {}
static void GenerateStubsAheadOfTime(Isolate* isolate);
@@ -189,7 +166,7 @@ class CodeStub BASE_EMBEDDED {
virtual bool SometimesSetsUpAFrame() { return true; }
// Lookup the code in the (possibly custom) cache.
- bool FindCodeInCache(Code** code_out, Isolate* isolate);
+ bool FindCodeInCache(Code** code_out);
// Returns information for computing the number key.
virtual Major MajorKey() = 0;
@@ -210,13 +187,15 @@ class CodeStub BASE_EMBEDDED {
// Returns a name for logging/debugging purposes.
SmartArrayPointer<const char> GetName();
+ Isolate* isolate() const { return isolate_; }
+
protected:
static bool CanUseFPRegisters();
// Generates the assembler code for the stub.
- virtual Handle<Code> GenerateCode(Isolate* isolate) = 0;
+ virtual Handle<Code> GenerateCode() = 0;
- virtual void VerifyPlatformFeatures(Isolate* isolate);
+ virtual void VerifyPlatformFeatures();
// Returns whether the code generated for this stub needs to be allocated as
// a fixed (non-moveable) code object.
@@ -228,7 +207,7 @@ class CodeStub BASE_EMBEDDED {
private:
// Perform bookkeeping required after code generation when stub code is
// initially generated.
- void RecordCodeGeneration(Code* code, Isolate* isolate);
+ void RecordCodeGeneration(Handle<Code> code);
// Finish the code object after it has been generated.
virtual void FinishCode(Handle<Code> code) { }
@@ -246,7 +225,7 @@ class CodeStub BASE_EMBEDDED {
virtual void AddToSpecialCache(Handle<Code> new_object) { }
// Find code in a specialized cache, work is delegated to the specific stub.
- virtual bool FindCodeInSpecialCache(Code** code_out, Isolate* isolate) {
+ virtual bool FindCodeInSpecialCache(Code** code_out) {
return false;
}
@@ -266,13 +245,17 @@ class CodeStub BASE_EMBEDDED {
kStubMajorKeyBits, kStubMinorKeyBits> {}; // NOLINT
friend class BreakPointIterator;
+
+ Isolate* isolate_;
};
class PlatformCodeStub : public CodeStub {
public:
+ explicit PlatformCodeStub(Isolate* isolate) : CodeStub(isolate) { }
+
// Retrieve the code for the stub. Generate the code if needed.
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual Code::Kind GetCodeKind() const { return Code::STUB; }
@@ -386,14 +369,15 @@ class HydrogenCodeStub : public CodeStub {
INITIALIZED
};
- explicit HydrogenCodeStub(InitializationState state = INITIALIZED) {
+ HydrogenCodeStub(Isolate* isolate, InitializationState state = INITIALIZED)
+ : CodeStub(isolate) {
is_uninitialized_ = (state == UNINITIALIZED);
}
virtual Code::Kind GetCodeKind() const { return Code::STUB; }
- CodeStubInterfaceDescriptor* GetInterfaceDescriptor(Isolate* isolate) {
- return isolate->code_stub_interface_descriptor(MajorKey());
+ CodeStubInterfaceDescriptor* GetInterfaceDescriptor() {
+ return isolate()->code_stub_interface_descriptor(MajorKey());
}
bool IsUninitialized() { return is_uninitialized_; }
@@ -405,15 +389,14 @@ class HydrogenCodeStub : public CodeStub {
}
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) = 0;
// Retrieve the code for the stub. Generate the code if needed.
- virtual Handle<Code> GenerateCode(Isolate* isolate) = 0;
+ virtual Handle<Code> GenerateCode() = 0;
virtual int NotMissMinorKey() = 0;
- Handle<Code> GenerateLightweightMissCode(Isolate* isolate);
+ Handle<Code> GenerateLightweightMissCode();
template<class StateType>
void TraceTransition(StateType from, StateType to);
@@ -494,18 +477,16 @@ class NopRuntimeCallHelper : public RuntimeCallHelper {
class ToNumberStub: public HydrogenCodeStub {
public:
- ToNumberStub() { }
+ explicit ToNumberStub(Isolate* isolate) : HydrogenCodeStub(isolate) { }
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
static void InstallDescriptors(Isolate* isolate) {
- ToNumberStub stub;
+ ToNumberStub stub(isolate);
stub.InitializeInterfaceDescriptor(
- isolate,
isolate->code_stub_interface_descriptor(CodeStub::ToNumber));
}
@@ -517,12 +498,11 @@ class ToNumberStub: public HydrogenCodeStub {
class NumberToStringStub V8_FINAL : public HydrogenCodeStub {
public:
- NumberToStringStub() {}
+ explicit NumberToStringStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
- virtual Handle<Code> GenerateCode(Isolate* isolate) V8_OVERRIDE;
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
static void InstallDescriptors(Isolate* isolate);
@@ -538,15 +518,17 @@ class NumberToStringStub V8_FINAL : public HydrogenCodeStub {
class FastNewClosureStub : public HydrogenCodeStub {
public:
- explicit FastNewClosureStub(StrictMode strict_mode, bool is_generator)
- : strict_mode_(strict_mode),
- is_generator_(is_generator) { }
+ FastNewClosureStub(Isolate* isolate,
+ StrictMode strict_mode,
+ bool is_generator)
+ : HydrogenCodeStub(isolate),
+ strict_mode_(strict_mode),
+ is_generator_(is_generator) { }
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
static void InstallDescriptors(Isolate* isolate);
@@ -572,15 +554,15 @@ class FastNewContextStub V8_FINAL : public HydrogenCodeStub {
public:
static const int kMaximumSlots = 64;
- explicit FastNewContextStub(int slots) : slots_(slots) {
+ FastNewContextStub(Isolate* isolate, int slots)
+ : HydrogenCodeStub(isolate), slots_(slots) {
ASSERT(slots_ > 0 && slots_ <= kMaximumSlots);
}
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
static void InstallDescriptors(Isolate* isolate);
@@ -611,10 +593,12 @@ class FastCloneShallowArrayStub : public HydrogenCodeStub {
static const int kFastCloneModeCount = LAST_CLONE_MODE + 1;
- FastCloneShallowArrayStub(Mode mode,
+ FastCloneShallowArrayStub(Isolate* isolate,
+ Mode mode,
AllocationSiteMode allocation_site_mode,
int length)
- : mode_(mode),
+ : HydrogenCodeStub(isolate),
+ mode_(mode),
allocation_site_mode_(allocation_site_mode),
length_((mode == COPY_ON_WRITE_ELEMENTS) ? 0 : length) {
ASSERT_GE(length_, 0);
@@ -641,11 +625,10 @@ class FastCloneShallowArrayStub : public HydrogenCodeStub {
return LAST_ELEMENTS_KIND;
}
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
static void InstallDescriptors(Isolate* isolate);
@@ -675,18 +658,18 @@ class FastCloneShallowObjectStub : public HydrogenCodeStub {
// Maximum number of properties in copied object.
static const int kMaximumClonedProperties = 6;
- explicit FastCloneShallowObjectStub(int length) : length_(length) {
+ FastCloneShallowObjectStub(Isolate* isolate, int length)
+ : HydrogenCodeStub(isolate), length_(length) {
ASSERT_GE(length_, 0);
ASSERT_LE(length_, kMaximumClonedProperties);
}
int length() const { return length_; }
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
private:
int length_;
@@ -700,15 +683,15 @@ class FastCloneShallowObjectStub : public HydrogenCodeStub {
class CreateAllocationSiteStub : public HydrogenCodeStub {
public:
- explicit CreateAllocationSiteStub() { }
+ explicit CreateAllocationSiteStub(Isolate* isolate)
+ : HydrogenCodeStub(isolate) { }
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
static void GenerateAheadOfTime(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
private:
Major MajorKey() { return CreateAllocationSite; }
@@ -727,7 +710,8 @@ class InstanceofStub: public PlatformCodeStub {
kReturnTrueFalseObject = 1 << 2
};
- explicit InstanceofStub(Flags flags) : flags_(flags) { }
+ InstanceofStub(Isolate* isolate, Flags flags)
+ : PlatformCodeStub(isolate), flags_(flags) { }
static Register left();
static Register right();
@@ -801,8 +785,8 @@ class MathPowStub: public PlatformCodeStub {
public:
enum ExponentType { INTEGER, DOUBLE, TAGGED, ON_STACK };
- explicit MathPowStub(ExponentType exponent_type)
- : exponent_type_(exponent_type) { }
+ MathPowStub(Isolate* isolate, ExponentType exponent_type)
+ : PlatformCodeStub(isolate), exponent_type_(exponent_type) { }
virtual void Generate(MacroAssembler* masm);
private:
@@ -815,7 +799,8 @@ class MathPowStub: public PlatformCodeStub {
class ICStub: public PlatformCodeStub {
public:
- explicit ICStub(Code::Kind kind) : kind_(kind) { }
+ ICStub(Isolate* isolate, Code::Kind kind)
+ : PlatformCodeStub(isolate), kind_(kind) { }
virtual Code::Kind GetCodeKind() const { return kind_; }
virtual InlineCacheState GetICState() { return MONOMORPHIC; }
@@ -839,9 +824,52 @@ class ICStub: public PlatformCodeStub {
};
+class CallICStub: public PlatformCodeStub {
+ public:
+ CallICStub(Isolate* isolate, const CallIC::State& state)
+ : PlatformCodeStub(isolate), state_(state) {}
+
+ bool CallAsMethod() const { return state_.CallAsMethod(); }
+
+ int arg_count() const { return state_.arg_count(); }
+
+ static int ExtractArgcFromMinorKey(int minor_key) {
+ CallIC::State state((ExtraICState) minor_key);
+ return state.arg_count();
+ }
+
+ virtual void Generate(MacroAssembler* masm);
+
+ virtual Code::Kind GetCodeKind() const V8_OVERRIDE {
+ return Code::CALL_IC;
+ }
+
+ virtual InlineCacheState GetICState() V8_FINAL V8_OVERRIDE {
+ return state_.GetICState();
+ }
+
+ virtual ExtraICState GetExtraICState() V8_FINAL V8_OVERRIDE {
+ return state_.GetExtraICState();
+ }
+
+ protected:
+ virtual int MinorKey() { return GetExtraICState(); }
+ virtual void PrintState(StringStream* stream) V8_FINAL V8_OVERRIDE;
+
+ private:
+ virtual CodeStub::Major MajorKey() { return CallIC; }
+
+ // Code generation helpers.
+ void GenerateMiss(MacroAssembler* masm);
+
+ CallIC::State state_;
+};
+
+
class FunctionPrototypeStub: public ICStub {
public:
- explicit FunctionPrototypeStub(Code::Kind kind) : ICStub(kind) { }
+ FunctionPrototypeStub(Isolate* isolate, Code::Kind kind)
+ : ICStub(isolate, kind) { }
virtual void Generate(MacroAssembler* masm);
private:
@@ -851,8 +879,8 @@ class FunctionPrototypeStub: public ICStub {
class StoreICStub: public ICStub {
public:
- StoreICStub(Code::Kind kind, StrictMode strict_mode)
- : ICStub(kind), strict_mode_(strict_mode) { }
+ StoreICStub(Isolate* isolate, Code::Kind kind, StrictMode strict_mode)
+ : ICStub(isolate, kind), strict_mode_(strict_mode) { }
protected:
virtual ExtraICState GetExtraICState() {
@@ -872,6 +900,7 @@ class StoreICStub: public ICStub {
class HICStub: public HydrogenCodeStub {
public:
+ explicit HICStub(Isolate* isolate) : HydrogenCodeStub(isolate) { }
virtual Code::Kind GetCodeKind() const { return kind(); }
virtual InlineCacheState GetICState() { return MONOMORPHIC; }
@@ -887,7 +916,7 @@ class HandlerStub: public HICStub {
virtual ExtraICState GetExtraICState() { return kind(); }
protected:
- HandlerStub() : HICStub() { }
+ explicit HandlerStub(Isolate* isolate) : HICStub(isolate) { }
virtual int NotMissMinorKey() { return bit_field_; }
int bit_field_;
};
@@ -895,15 +924,17 @@ class HandlerStub: public HICStub {
class LoadFieldStub: public HandlerStub {
public:
- LoadFieldStub(bool inobject, int index, Representation representation) {
+ LoadFieldStub(Isolate* isolate,
+ bool inobject,
+ int index, Representation representation)
+ : HandlerStub(isolate) {
Initialize(Code::LOAD_IC, inobject, index, representation);
}
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
Representation representation() {
if (unboxed_double()) return Representation::Double();
@@ -932,7 +963,7 @@ class LoadFieldStub: public HandlerStub {
virtual Code::StubType GetStubType() { return Code::FAST; }
protected:
- LoadFieldStub() : HandlerStub() { }
+ explicit LoadFieldStub(Isolate* isolate) : HandlerStub(isolate) { }
void Initialize(Code::Kind kind,
bool inobject,
@@ -955,13 +986,12 @@ class LoadFieldStub: public HandlerStub {
class StringLengthStub: public HandlerStub {
public:
- explicit StringLengthStub() : HandlerStub() {
+ explicit StringLengthStub(Isolate* isolate) : HandlerStub(isolate) {
Initialize(Code::LOAD_IC);
}
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
protected:
virtual Code::Kind kind() const {
@@ -979,12 +1009,11 @@ class StringLengthStub: public HandlerStub {
class KeyedStringLengthStub: public StringLengthStub {
public:
- explicit KeyedStringLengthStub() : StringLengthStub() {
+ explicit KeyedStringLengthStub(Isolate* isolate) : StringLengthStub(isolate) {
Initialize(Code::KEYED_LOAD_IC);
}
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
private:
virtual CodeStub::Major MajorKey() { return KeyedStringLength; }
@@ -993,7 +1022,8 @@ class KeyedStringLengthStub: public StringLengthStub {
class StoreGlobalStub : public HandlerStub {
public:
- explicit StoreGlobalStub(bool is_constant, bool check_global) {
+ StoreGlobalStub(Isolate* isolate, bool is_constant, bool check_global)
+ : HandlerStub(isolate) {
bit_field_ = IsConstantBits::encode(is_constant) |
CheckGlobalBits::encode(check_global);
}
@@ -1002,29 +1032,27 @@ class StoreGlobalStub : public HandlerStub {
return isolate->factory()->uninitialized_value();
}
- Handle<Code> GetCodeCopyFromTemplate(Isolate* isolate,
- Handle<GlobalObject> global,
+ Handle<Code> GetCodeCopyFromTemplate(Handle<GlobalObject> global,
Handle<PropertyCell> cell) {
if (check_global()) {
Code::FindAndReplacePattern pattern;
- pattern.Add(Handle<Map>(global_placeholder(isolate)->map()), global);
- pattern.Add(isolate->factory()->meta_map(), Handle<Map>(global->map()));
- pattern.Add(isolate->factory()->global_property_cell_map(), cell);
- return CodeStub::GetCodeCopy(isolate, pattern);
+ pattern.Add(Handle<Map>(global_placeholder(isolate())->map()), global);
+ pattern.Add(isolate()->factory()->meta_map(), Handle<Map>(global->map()));
+ pattern.Add(isolate()->factory()->global_property_cell_map(), cell);
+ return CodeStub::GetCodeCopy(pattern);
} else {
Code::FindAndReplacePattern pattern;
- pattern.Add(isolate->factory()->global_property_cell_map(), cell);
- return CodeStub::GetCodeCopy(isolate, pattern);
+ pattern.Add(isolate()->factory()->global_property_cell_map(), cell);
+ return CodeStub::GetCodeCopy(pattern);
}
}
virtual Code::Kind kind() const { return Code::STORE_IC; }
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
bool is_constant() const {
return IsConstantBits::decode(bit_field_);
@@ -1056,9 +1084,10 @@ class StoreGlobalStub : public HandlerStub {
class CallApiFunctionStub : public PlatformCodeStub {
public:
- CallApiFunctionStub(bool is_store,
+ CallApiFunctionStub(Isolate* isolate,
+ bool is_store,
bool call_data_undefined,
- int argc) {
+ int argc) : PlatformCodeStub(isolate) {
bit_field_ =
IsStoreBits::encode(is_store) |
CallDataUndefinedBits::encode(call_data_undefined) |
@@ -1083,7 +1112,7 @@ class CallApiFunctionStub : public PlatformCodeStub {
class CallApiGetterStub : public PlatformCodeStub {
public:
- CallApiGetterStub() {}
+ explicit CallApiGetterStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
private:
virtual void Generate(MacroAssembler* masm) V8_OVERRIDE;
@@ -1096,14 +1125,15 @@ class CallApiGetterStub : public PlatformCodeStub {
class KeyedLoadFieldStub: public LoadFieldStub {
public:
- KeyedLoadFieldStub(bool inobject, int index, Representation representation)
- : LoadFieldStub() {
+ KeyedLoadFieldStub(Isolate* isolate,
+ bool inobject,
+ int index, Representation representation)
+ : LoadFieldStub(isolate) {
Initialize(Code::KEYED_LOAD_IC, inobject, index, representation);
}
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
private:
virtual CodeStub::Major MajorKey() { return KeyedLoadField; }
@@ -1112,15 +1142,16 @@ class KeyedLoadFieldStub: public LoadFieldStub {
class BinaryOpICStub : public HydrogenCodeStub {
public:
- BinaryOpICStub(Token::Value op, OverwriteMode mode)
- : HydrogenCodeStub(UNINITIALIZED), state_(op, mode) {}
+ BinaryOpICStub(Isolate* isolate, Token::Value op, OverwriteMode mode)
+ : HydrogenCodeStub(isolate, UNINITIALIZED), state_(isolate, op, mode) {}
- explicit BinaryOpICStub(const BinaryOpIC::State& state) : state_(state) {}
+ BinaryOpICStub(Isolate* isolate, const BinaryOpIC::State& state)
+ : HydrogenCodeStub(isolate), state_(state) {}
static void GenerateAheadOfTime(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
static void InstallDescriptors(Isolate* isolate);
@@ -1136,11 +1167,11 @@ class BinaryOpICStub : public HydrogenCodeStub {
return state_.GetExtraICState();
}
- virtual void VerifyPlatformFeatures(Isolate* isolate) V8_FINAL V8_OVERRIDE {
+ virtual void VerifyPlatformFeatures() V8_FINAL V8_OVERRIDE {
ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
}
- virtual Handle<Code> GenerateCode(Isolate* isolate) V8_OVERRIDE;
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
const BinaryOpIC::State& state() const { return state_; }
@@ -1165,44 +1196,20 @@ class BinaryOpICStub : public HydrogenCodeStub {
};
-class ArrayPushStub: public PlatformCodeStub {
- public:
- ArrayPushStub(ElementsKind kind, int argc) {
- bit_field_ = ElementsKindBits::encode(kind) | ArgcBits::encode(argc);
- }
-
- void Generate(MacroAssembler* masm);
-
- private:
- int arguments_count() { return ArgcBits::decode(bit_field_); }
- ElementsKind elements_kind() {
- return ElementsKindBits::decode(bit_field_);
- }
-
- virtual CodeStub::Major MajorKey() { return ArrayPush; }
- virtual int MinorKey() { return bit_field_; }
-
- class ElementsKindBits: public BitField<ElementsKind, 0, 3> {};
- class ArgcBits: public BitField<int, 3, Code::kArgumentsBits> {};
-
- int bit_field_;
-};
-
-
// TODO(bmeurer): Merge this into the BinaryOpICStub once we have proper tail
// call support for stubs in Hydrogen.
class BinaryOpICWithAllocationSiteStub V8_FINAL : public PlatformCodeStub {
public:
- explicit BinaryOpICWithAllocationSiteStub(const BinaryOpIC::State& state)
- : state_(state) {}
+ BinaryOpICWithAllocationSiteStub(Isolate* isolate,
+ const BinaryOpIC::State& state)
+ : PlatformCodeStub(isolate), state_(state) {}
static void GenerateAheadOfTime(Isolate* isolate);
- Handle<Code> GetCodeCopyFromTemplate(Isolate* isolate,
- Handle<AllocationSite> allocation_site) {
+ Handle<Code> GetCodeCopyFromTemplate(Handle<AllocationSite> allocation_site) {
Code::FindAndReplacePattern pattern;
- pattern.Add(isolate->factory()->oddball_map(), allocation_site);
- return CodeStub::GetCodeCopy(isolate, pattern);
+ pattern.Add(isolate()->factory()->undefined_map(), allocation_site);
+ return CodeStub::GetCodeCopy(pattern);
}
virtual Code::Kind GetCodeKind() const V8_OVERRIDE {
@@ -1217,7 +1224,7 @@ class BinaryOpICWithAllocationSiteStub V8_FINAL : public PlatformCodeStub {
return state_.GetExtraICState();
}
- virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
+ virtual void VerifyPlatformFeatures() V8_OVERRIDE {
ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
}
@@ -1240,14 +1247,17 @@ class BinaryOpICWithAllocationSiteStub V8_FINAL : public PlatformCodeStub {
class BinaryOpWithAllocationSiteStub V8_FINAL : public BinaryOpICStub {
public:
- BinaryOpWithAllocationSiteStub(Token::Value op, OverwriteMode mode)
- : BinaryOpICStub(op, mode) {}
+ BinaryOpWithAllocationSiteStub(Isolate* isolate,
+ Token::Value op,
+ OverwriteMode mode)
+ : BinaryOpICStub(isolate, op, mode) {}
- explicit BinaryOpWithAllocationSiteStub(const BinaryOpIC::State& state)
- : BinaryOpICStub(state) {}
+ BinaryOpWithAllocationSiteStub(Isolate* isolate,
+ const BinaryOpIC::State& state)
+ : BinaryOpICStub(isolate, state) {}
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
static void InstallDescriptors(Isolate* isolate);
@@ -1255,7 +1265,7 @@ class BinaryOpWithAllocationSiteStub V8_FINAL : public BinaryOpICStub {
return Code::STUB;
}
- virtual Handle<Code> GenerateCode(Isolate* isolate) V8_OVERRIDE;
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual Major MajorKey() V8_OVERRIDE {
return BinaryOpWithAllocationSite;
@@ -1282,8 +1292,11 @@ enum StringAddFlags {
class StringAddStub V8_FINAL : public HydrogenCodeStub {
public:
- StringAddStub(StringAddFlags flags, PretenureFlag pretenure_flag)
- : bit_field_(StringAddFlagsBits::encode(flags) |
+ StringAddStub(Isolate* isolate,
+ StringAddFlags flags,
+ PretenureFlag pretenure_flag)
+ : HydrogenCodeStub(isolate),
+ bit_field_(StringAddFlagsBits::encode(flags) |
PretenureFlagBits::encode(pretenure_flag)) {}
StringAddFlags flags() const {
@@ -1294,14 +1307,13 @@ class StringAddStub V8_FINAL : public HydrogenCodeStub {
return PretenureFlagBits::decode(bit_field_);
}
- virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
+ virtual void VerifyPlatformFeatures() V8_OVERRIDE {
ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
}
- virtual Handle<Code> GenerateCode(Isolate* isolate) V8_OVERRIDE;
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
static void InstallDescriptors(Isolate* isolate);
@@ -1326,11 +1338,13 @@ class StringAddStub V8_FINAL : public HydrogenCodeStub {
class ICCompareStub: public PlatformCodeStub {
public:
- ICCompareStub(Token::Value op,
+ ICCompareStub(Isolate* isolate,
+ Token::Value op,
CompareIC::State left,
CompareIC::State right,
CompareIC::State handler)
- : op_(op),
+ : PlatformCodeStub(isolate),
+ op_(op),
left_(left),
right_(right),
state_(handler) {
@@ -1378,7 +1392,7 @@ class ICCompareStub: public PlatformCodeStub {
Condition GetCondition() const { return CompareIC::ComputeCondition(op_); }
virtual void AddToSpecialCache(Handle<Code> new_object);
- virtual bool FindCodeInSpecialCache(Code** code_out, Isolate* isolate);
+ virtual bool FindCodeInSpecialCache(Code** code_out);
virtual bool UseSpecialCache() { return state_ == CompareIC::KNOWN_OBJECT; }
Token::Value op_;
@@ -1394,28 +1408,28 @@ class CompareNilICStub : public HydrogenCodeStub {
Type* GetType(Zone* zone, Handle<Map> map = Handle<Map>());
Type* GetInputType(Zone* zone, Handle<Map> map);
- explicit CompareNilICStub(NilValue nil) : nil_value_(nil) { }
+ CompareNilICStub(Isolate* isolate, NilValue nil)
+ : HydrogenCodeStub(isolate), nil_value_(nil) { }
- CompareNilICStub(ExtraICState ic_state,
+ CompareNilICStub(Isolate* isolate,
+ ExtraICState ic_state,
InitializationState init_state = INITIALIZED)
- : HydrogenCodeStub(init_state),
+ : HydrogenCodeStub(isolate, init_state),
nil_value_(NilValueField::decode(ic_state)),
state_(State(TypesField::decode(ic_state))) {
}
static Handle<Code> GetUninitialized(Isolate* isolate,
NilValue nil) {
- return CompareNilICStub(nil, UNINITIALIZED).GetCode(isolate);
+ return CompareNilICStub(isolate, nil, UNINITIALIZED).GetCode();
}
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
static void InstallDescriptors(Isolate* isolate) {
- CompareNilICStub compare_stub(kNullValue, UNINITIALIZED);
+ CompareNilICStub compare_stub(isolate, kNullValue, UNINITIALIZED);
compare_stub.InitializeInterfaceDescriptor(
- isolate,
isolate->code_stub_interface_descriptor(CodeStub::CompareNilIC));
}
@@ -1431,7 +1445,7 @@ class CompareNilICStub : public HydrogenCodeStub {
virtual Code::Kind GetCodeKind() const { return Code::COMPARE_NIL_IC; }
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual ExtraICState GetExtraICState() {
return NilValueField::encode(nil_value_) |
@@ -1471,8 +1485,10 @@ class CompareNilICStub : public HydrogenCodeStub {
void Print(StringStream* stream) const;
};
- CompareNilICStub(NilValue nil, InitializationState init_state)
- : HydrogenCodeStub(init_state), nil_value_(nil) { }
+ CompareNilICStub(Isolate* isolate,
+ NilValue nil,
+ InitializationState init_state)
+ : HydrogenCodeStub(isolate, init_state), nil_value_(nil) { }
class NilValueField : public BitField<NilValue, 0, 1> {};
class TypesField : public BitField<byte, 1, NUMBER_OF_TYPES> {};
@@ -1489,9 +1505,12 @@ class CompareNilICStub : public HydrogenCodeStub {
class CEntryStub : public PlatformCodeStub {
public:
- explicit CEntryStub(int result_size,
- SaveFPRegsMode save_doubles = kDontSaveFPRegs)
- : result_size_(result_size), save_doubles_(save_doubles) { }
+ CEntryStub(Isolate* isolate,
+ int result_size,
+ SaveFPRegsMode save_doubles = kDontSaveFPRegs)
+ : PlatformCodeStub(isolate),
+ result_size_(result_size),
+ save_doubles_(save_doubles) { }
void Generate(MacroAssembler* masm);
@@ -1502,19 +1521,12 @@ class CEntryStub : public PlatformCodeStub {
static void GenerateAheadOfTime(Isolate* isolate);
protected:
- virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
+ virtual void VerifyPlatformFeatures() V8_OVERRIDE {
ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
};
private:
- void GenerateCore(MacroAssembler* masm,
- Label* throw_normal_exception,
- Label* throw_termination_exception,
- bool do_gc,
- bool always_allocate_scope);
-
// Number of pointers/values returned.
- Isolate* isolate_;
const int result_size_;
SaveFPRegsMode save_doubles_;
@@ -1527,7 +1539,7 @@ class CEntryStub : public PlatformCodeStub {
class JSEntryStub : public PlatformCodeStub {
public:
- JSEntryStub() { }
+ explicit JSEntryStub(Isolate* isolate) : PlatformCodeStub(isolate) { }
void Generate(MacroAssembler* masm) { GenerateBody(masm, false); }
@@ -1546,7 +1558,7 @@ class JSEntryStub : public PlatformCodeStub {
class JSConstructEntryStub : public JSEntryStub {
public:
- JSConstructEntryStub() { }
+ explicit JSConstructEntryStub(Isolate* isolate) : JSEntryStub(isolate) { }
void Generate(MacroAssembler* masm) { GenerateBody(masm, true); }
@@ -1568,7 +1580,8 @@ class ArgumentsAccessStub: public PlatformCodeStub {
NEW_STRICT
};
- explicit ArgumentsAccessStub(Type type) : type_(type) { }
+ ArgumentsAccessStub(Isolate* isolate, Type type)
+ : PlatformCodeStub(isolate), type_(type) { }
private:
Type type_;
@@ -1588,7 +1601,7 @@ class ArgumentsAccessStub: public PlatformCodeStub {
class RegExpExecStub: public PlatformCodeStub {
public:
- RegExpExecStub() { }
+ explicit RegExpExecStub(Isolate* isolate) : PlatformCodeStub(isolate) { }
private:
Major MajorKey() { return RegExpExec; }
@@ -1600,12 +1613,12 @@ class RegExpExecStub: public PlatformCodeStub {
class RegExpConstructResultStub V8_FINAL : public HydrogenCodeStub {
public:
- RegExpConstructResultStub() { }
+ explicit RegExpConstructResultStub(Isolate* isolate)
+ : HydrogenCodeStub(isolate) { }
- virtual Handle<Code> GenerateCode(Isolate* isolate) V8_OVERRIDE;
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
virtual Major MajorKey() V8_OVERRIDE { return RegExpConstructResult; }
@@ -1625,15 +1638,11 @@ class RegExpConstructResultStub V8_FINAL : public HydrogenCodeStub {
class CallFunctionStub: public PlatformCodeStub {
public:
- CallFunctionStub(int argc, CallFunctionFlags flags)
- : argc_(argc), flags_(flags) { }
+ CallFunctionStub(Isolate* isolate, int argc, CallFunctionFlags flags)
+ : PlatformCodeStub(isolate), argc_(argc), flags_(flags) { }
void Generate(MacroAssembler* masm);
- virtual void FinishCode(Handle<Code> code) {
- code->set_has_function_cache(RecordCallTarget());
- }
-
static int ExtractArgcFromMinorKey(int minor_key) {
return ArgcBits::decode(minor_key);
}
@@ -1654,10 +1663,6 @@ class CallFunctionStub: public PlatformCodeStub {
return FlagBits::encode(flags_) | ArgcBits::encode(argc_);
}
- bool RecordCallTarget() {
- return flags_ == RECORD_CALL_TARGET;
- }
-
bool CallAsMethod() {
return flags_ == CALL_AS_METHOD || flags_ == WRAP_AND_CALL;
}
@@ -1670,7 +1675,8 @@ class CallFunctionStub: public PlatformCodeStub {
class CallConstructStub: public PlatformCodeStub {
public:
- explicit CallConstructStub(CallFunctionFlags flags) : flags_(flags) {}
+ CallConstructStub(Isolate* isolate, CallConstructorFlags flags)
+ : PlatformCodeStub(isolate), flags_(flags) {}
void Generate(MacroAssembler* masm);
@@ -1679,7 +1685,7 @@ class CallConstructStub: public PlatformCodeStub {
}
private:
- CallFunctionFlags flags_;
+ CallConstructorFlags flags_;
virtual void PrintName(StringStream* stream);
@@ -1687,11 +1693,7 @@ class CallConstructStub: public PlatformCodeStub {
int MinorKey() { return flags_; }
bool RecordCallTarget() {
- return (flags_ & RECORD_CALL_TARGET) != 0;
- }
-
- bool CallAsMethod() {
- return (flags_ & CALL_AS_METHOD) != 0;
+ return (flags_ & RECORD_CONSTRUCTOR_TARGET) != 0;
}
};
@@ -1872,12 +1874,12 @@ class StringCharAtGenerator {
class KeyedLoadDictionaryElementStub : public HydrogenCodeStub {
public:
- KeyedLoadDictionaryElementStub() {}
+ explicit KeyedLoadDictionaryElementStub(Isolate* isolate)
+ : HydrogenCodeStub(isolate) {}
- virtual Handle<Code> GenerateCode(Isolate* isolate) V8_OVERRIDE;
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
private:
@@ -1890,7 +1892,8 @@ class KeyedLoadDictionaryElementStub : public HydrogenCodeStub {
class KeyedLoadDictionaryElementPlatformStub : public PlatformCodeStub {
public:
- KeyedLoadDictionaryElementPlatformStub() {}
+ explicit KeyedLoadDictionaryElementPlatformStub(Isolate* isolate)
+ : PlatformCodeStub(isolate) {}
void Generate(MacroAssembler* masm);
@@ -1904,18 +1907,21 @@ class KeyedLoadDictionaryElementPlatformStub : public PlatformCodeStub {
class DoubleToIStub : public PlatformCodeStub {
public:
- DoubleToIStub(Register source,
+ DoubleToIStub(Isolate* isolate,
+ Register source,
Register destination,
int offset,
bool is_truncating,
- bool skip_fastpath = false) : bit_field_(0) {
+ bool skip_fastpath = false)
+ : PlatformCodeStub(isolate), bit_field_(0) {
bit_field_ = SourceRegisterBits::encode(source.code()) |
DestinationRegisterBits::encode(destination.code()) |
OffsetBits::encode(offset) |
IsTruncatingBits::encode(is_truncating) |
SkipFastPathBits::encode(skip_fastpath) |
- SSEBits::encode(CpuFeatures::IsSafeForSnapshot(SSE2) ?
- CpuFeatures::IsSafeForSnapshot(SSE3) ? 2 : 1 : 0);
+ SSEBits::encode(
+ CpuFeatures::IsSafeForSnapshot(isolate, SSE2) ?
+ CpuFeatures::IsSafeForSnapshot(isolate, SSE3) ? 2 : 1 : 0);
}
Register source() {
@@ -1943,7 +1949,7 @@ class DoubleToIStub : public PlatformCodeStub {
virtual bool SometimesSetsUpAFrame() { return false; }
protected:
- virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
+ virtual void VerifyPlatformFeatures() V8_OVERRIDE {
ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
}
@@ -1975,7 +1981,10 @@ class DoubleToIStub : public PlatformCodeStub {
class KeyedLoadFastElementStub : public HydrogenCodeStub {
public:
- KeyedLoadFastElementStub(bool is_js_array, ElementsKind elements_kind) {
+ KeyedLoadFastElementStub(Isolate* isolate,
+ bool is_js_array,
+ ElementsKind elements_kind)
+ : HydrogenCodeStub(isolate) {
bit_field_ = ElementsKindBits::encode(elements_kind) |
IsJSArrayBits::encode(is_js_array);
}
@@ -1988,11 +1997,10 @@ class KeyedLoadFastElementStub : public HydrogenCodeStub {
return ElementsKindBits::decode(bit_field_);
}
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
private:
class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
@@ -2008,9 +2016,11 @@ class KeyedLoadFastElementStub : public HydrogenCodeStub {
class KeyedStoreFastElementStub : public HydrogenCodeStub {
public:
- KeyedStoreFastElementStub(bool is_js_array,
+ KeyedStoreFastElementStub(Isolate* isolate,
+ bool is_js_array,
ElementsKind elements_kind,
- KeyedAccessStoreMode mode) {
+ KeyedAccessStoreMode mode)
+ : HydrogenCodeStub(isolate) {
bit_field_ = ElementsKindBits::encode(elements_kind) |
IsJSArrayBits::encode(is_js_array) |
StoreModeBits::encode(mode);
@@ -2028,11 +2038,10 @@ class KeyedStoreFastElementStub : public HydrogenCodeStub {
return StoreModeBits::decode(bit_field_);
}
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
private:
class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
@@ -2049,9 +2058,10 @@ class KeyedStoreFastElementStub : public HydrogenCodeStub {
class TransitionElementsKindStub : public HydrogenCodeStub {
public:
- TransitionElementsKindStub(ElementsKind from_kind,
+ TransitionElementsKindStub(Isolate* isolate,
+ ElementsKind from_kind,
ElementsKind to_kind,
- bool is_js_array) {
+ bool is_js_array) : HydrogenCodeStub(isolate) {
bit_field_ = FromKindBits::encode(from_kind) |
ToKindBits::encode(to_kind) |
IsJSArrayBits::encode(is_js_array);
@@ -2069,11 +2079,10 @@ class TransitionElementsKindStub : public HydrogenCodeStub {
return IsJSArrayBits::decode(bit_field_);
}
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
private:
class FromKindBits: public BitField<ElementsKind, 8, 8> {};
@@ -2090,8 +2099,10 @@ class TransitionElementsKindStub : public HydrogenCodeStub {
class ArrayConstructorStubBase : public HydrogenCodeStub {
public:
- ArrayConstructorStubBase(ElementsKind kind,
- AllocationSiteOverrideMode override_mode) {
+ ArrayConstructorStubBase(Isolate* isolate,
+ ElementsKind kind,
+ AllocationSiteOverrideMode override_mode)
+ : HydrogenCodeStub(isolate) {
// It only makes sense to override local allocation site behavior
// if there is a difference between the global allocation site policy
// for an ElementsKind and the desired usage of the stub.
@@ -2137,16 +2148,16 @@ class ArrayConstructorStubBase : public HydrogenCodeStub {
class ArrayNoArgumentConstructorStub : public ArrayConstructorStubBase {
public:
ArrayNoArgumentConstructorStub(
+ Isolate* isolate,
ElementsKind kind,
AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
- : ArrayConstructorStubBase(kind, override_mode) {
+ : ArrayConstructorStubBase(isolate, kind, override_mode) {
}
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
private:
Major MajorKey() { return ArrayNoArgumentConstructor; }
@@ -2162,16 +2173,16 @@ class ArrayNoArgumentConstructorStub : public ArrayConstructorStubBase {
class ArraySingleArgumentConstructorStub : public ArrayConstructorStubBase {
public:
ArraySingleArgumentConstructorStub(
+ Isolate* isolate,
ElementsKind kind,
AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
- : ArrayConstructorStubBase(kind, override_mode) {
+ : ArrayConstructorStubBase(isolate, kind, override_mode) {
}
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
private:
Major MajorKey() { return ArraySingleArgumentConstructor; }
@@ -2187,16 +2198,16 @@ class ArraySingleArgumentConstructorStub : public ArrayConstructorStubBase {
class ArrayNArgumentsConstructorStub : public ArrayConstructorStubBase {
public:
ArrayNArgumentsConstructorStub(
+ Isolate* isolate,
ElementsKind kind,
AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
- : ArrayConstructorStubBase(kind, override_mode) {
+ : ArrayConstructorStubBase(isolate, kind, override_mode) {
}
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
private:
Major MajorKey() { return ArrayNArgumentsConstructor; }
@@ -2211,7 +2222,8 @@ class ArrayNArgumentsConstructorStub : public ArrayConstructorStubBase {
class InternalArrayConstructorStubBase : public HydrogenCodeStub {
public:
- explicit InternalArrayConstructorStubBase(ElementsKind kind) {
+ InternalArrayConstructorStubBase(Isolate* isolate, ElementsKind kind)
+ : HydrogenCodeStub(isolate) {
kind_ = kind;
}
@@ -2235,14 +2247,14 @@ class InternalArrayConstructorStubBase : public HydrogenCodeStub {
class InternalArrayNoArgumentConstructorStub : public
InternalArrayConstructorStubBase {
public:
- explicit InternalArrayNoArgumentConstructorStub(ElementsKind kind)
- : InternalArrayConstructorStubBase(kind) { }
+ InternalArrayNoArgumentConstructorStub(Isolate* isolate,
+ ElementsKind kind)
+ : InternalArrayConstructorStubBase(isolate, kind) { }
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
private:
Major MajorKey() { return InternalArrayNoArgumentConstructor; }
@@ -2254,14 +2266,14 @@ class InternalArrayNoArgumentConstructorStub : public
class InternalArraySingleArgumentConstructorStub : public
InternalArrayConstructorStubBase {
public:
- explicit InternalArraySingleArgumentConstructorStub(ElementsKind kind)
- : InternalArrayConstructorStubBase(kind) { }
+ InternalArraySingleArgumentConstructorStub(Isolate* isolate,
+ ElementsKind kind)
+ : InternalArrayConstructorStubBase(isolate, kind) { }
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
private:
Major MajorKey() { return InternalArraySingleArgumentConstructor; }
@@ -2273,14 +2285,13 @@ class InternalArraySingleArgumentConstructorStub : public
class InternalArrayNArgumentsConstructorStub : public
InternalArrayConstructorStubBase {
public:
- explicit InternalArrayNArgumentsConstructorStub(ElementsKind kind)
- : InternalArrayConstructorStubBase(kind) { }
+ InternalArrayNArgumentsConstructorStub(Isolate* isolate, ElementsKind kind)
+ : InternalArrayConstructorStubBase(isolate, kind) { }
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
private:
Major MajorKey() { return InternalArrayNArgumentsConstructor; }
@@ -2291,10 +2302,12 @@ class InternalArrayNArgumentsConstructorStub : public
class KeyedStoreElementStub : public PlatformCodeStub {
public:
- KeyedStoreElementStub(bool is_js_array,
+ KeyedStoreElementStub(Isolate* isolate,
+ bool is_js_array,
ElementsKind elements_kind,
KeyedAccessStoreMode store_mode)
- : is_js_array_(is_js_array),
+ : PlatformCodeStub(isolate),
+ is_js_array_(is_js_array),
elements_kind_(elements_kind),
store_mode_(store_mode),
fp_registers_(CanUseFPRegisters()) { }
@@ -2357,18 +2370,17 @@ class ToBooleanStub: public HydrogenCodeStub {
static Types Generic() { return Types((1 << NUMBER_OF_TYPES) - 1); }
};
- explicit ToBooleanStub(Types types = Types())
- : types_(types) { }
- explicit ToBooleanStub(ExtraICState state)
- : types_(static_cast<byte>(state)) { }
+ ToBooleanStub(Isolate* isolate, Types types = Types())
+ : HydrogenCodeStub(isolate), types_(types) { }
+ ToBooleanStub(Isolate* isolate, ExtraICState state)
+ : HydrogenCodeStub(isolate), types_(static_cast<byte>(state)) { }
bool UpdateStatus(Handle<Object> object);
Types GetTypes() { return types_; }
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
virtual void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
virtual Code::Kind GetCodeKind() const { return Code::TO_BOOLEAN_IC; }
virtual void PrintState(StringStream* stream);
@@ -2376,14 +2388,13 @@ class ToBooleanStub: public HydrogenCodeStub {
virtual bool SometimesSetsUpAFrame() { return false; }
static void InstallDescriptors(Isolate* isolate) {
- ToBooleanStub stub;
+ ToBooleanStub stub(isolate);
stub.InitializeInterfaceDescriptor(
- isolate,
isolate->code_stub_interface_descriptor(CodeStub::ToBoolean));
}
static Handle<Code> GetUninitialized(Isolate* isolate) {
- return ToBooleanStub(UNINITIALIZED).GetCode(isolate);
+ return ToBooleanStub(isolate, UNINITIALIZED).GetCode();
}
virtual ExtraICState GetExtraICState() {
@@ -2402,8 +2413,8 @@ class ToBooleanStub: public HydrogenCodeStub {
Major MajorKey() { return ToBoolean; }
int NotMissMinorKey() { return GetExtraICState(); }
- explicit ToBooleanStub(InitializationState init_state) :
- HydrogenCodeStub(init_state) {}
+ ToBooleanStub(Isolate* isolate, InitializationState init_state) :
+ HydrogenCodeStub(isolate, init_state) {}
Types types_;
};
@@ -2411,11 +2422,13 @@ class ToBooleanStub: public HydrogenCodeStub {
class ElementsTransitionAndStoreStub : public HydrogenCodeStub {
public:
- ElementsTransitionAndStoreStub(ElementsKind from_kind,
+ ElementsTransitionAndStoreStub(Isolate* isolate,
+ ElementsKind from_kind,
ElementsKind to_kind,
bool is_jsarray,
KeyedAccessStoreMode store_mode)
- : from_kind_(from_kind),
+ : HydrogenCodeStub(isolate),
+ from_kind_(from_kind),
to_kind_(to_kind),
is_jsarray_(is_jsarray),
store_mode_(store_mode) {}
@@ -2425,11 +2438,10 @@ class ElementsTransitionAndStoreStub : public HydrogenCodeStub {
bool is_jsarray() const { return is_jsarray_; }
KeyedAccessStoreMode store_mode() const { return store_mode_; }
- virtual Handle<Code> GenerateCode(Isolate* isolate);
+ virtual Handle<Code> GenerateCode() V8_OVERRIDE;
- void InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor);
+ virtual void InitializeInterfaceDescriptor(
+ CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
private:
class FromBits: public BitField<ElementsKind, 0, 8> {};
@@ -2456,8 +2468,8 @@ class ElementsTransitionAndStoreStub : public HydrogenCodeStub {
class StoreArrayLiteralElementStub : public PlatformCodeStub {
public:
- StoreArrayLiteralElementStub()
- : fp_registers_(CanUseFPRegisters()) { }
+ explicit StoreArrayLiteralElementStub(Isolate* isolate)
+ : PlatformCodeStub(isolate), fp_registers_(CanUseFPRegisters()) { }
private:
class FPRegisters: public BitField<bool, 0, 1> {};
@@ -2475,8 +2487,10 @@ class StoreArrayLiteralElementStub : public PlatformCodeStub {
class StubFailureTrampolineStub : public PlatformCodeStub {
public:
- explicit StubFailureTrampolineStub(StubFunctionMode function_mode)
- : fp_registers_(CanUseFPRegisters()), function_mode_(function_mode) {}
+ StubFailureTrampolineStub(Isolate* isolate, StubFunctionMode function_mode)
+ : PlatformCodeStub(isolate),
+ fp_registers_(CanUseFPRegisters()),
+ function_mode_(function_mode) {}
static void GenerateAheadOfTime(Isolate* isolate);
@@ -2501,7 +2515,7 @@ class StubFailureTrampolineStub : public PlatformCodeStub {
class ProfileEntryHookStub : public PlatformCodeStub {
public:
- explicit ProfileEntryHookStub() {}
+ explicit ProfileEntryHookStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
// The profile entry hook function is not allowed to cause a GC.
virtual bool SometimesSetsUpAFrame() { return false; }
diff --git a/deps/v8/src/code.h b/deps/v8/src/code.h
index 791420cf39..40a6950d20 100644
--- a/deps/v8/src/code.h
+++ b/deps/v8/src/code.h
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_CODE_H_
#define V8_CODE_H_
diff --git a/deps/v8/src/codegen.cc b/deps/v8/src/codegen.cc
index ea0ead3104..9da4ea21e5 100644
--- a/deps/v8/src/codegen.cc
+++ b/deps/v8/src/codegen.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -40,6 +17,65 @@
namespace v8 {
namespace internal {
+
+#if defined(_WIN64)
+typedef double (*ModuloFunction)(double, double);
+static ModuloFunction modulo_function = NULL;
+// Defined in codegen-x64.cc.
+ModuloFunction CreateModuloFunction();
+
+void init_modulo_function() {
+ modulo_function = CreateModuloFunction();
+}
+
+
+double modulo(double x, double y) {
+ // Note: here we rely on dependent reads being ordered. This is true
+ // on all architectures we currently support.
+ return (*modulo_function)(x, y);
+}
+#elif defined(_WIN32)
+
+double modulo(double x, double y) {
+ // Workaround MS fmod bugs. ECMA-262 says:
+ // dividend is finite and divisor is an infinity => result equals dividend
+ // dividend is a zero and divisor is nonzero finite => result equals dividend
+ if (!(std::isfinite(x) && (!std::isfinite(y) && !std::isnan(y))) &&
+ !(x == 0 && (y != 0 && std::isfinite(y)))) {
+ x = fmod(x, y);
+ }
+ return x;
+}
+#else // POSIX
+
+double modulo(double x, double y) {
+ return std::fmod(x, y);
+}
+#endif // defined(_WIN64)
+
+
+#define UNARY_MATH_FUNCTION(name, generator) \
+static UnaryMathFunction fast_##name##_function = NULL; \
+void init_fast_##name##_function() { \
+ fast_##name##_function = generator; \
+} \
+double fast_##name(double x) { \
+ return (*fast_##name##_function)(x); \
+}
+
+UNARY_MATH_FUNCTION(exp, CreateExpFunction())
+UNARY_MATH_FUNCTION(sqrt, CreateSqrtFunction())
+
+#undef UNARY_MATH_FUNCTION
+
+
+void lazily_initialize_fast_exp() {
+ if (fast_exp_function == NULL) {
+ init_fast_exp_function();
+ }
+}
+
+
#define __ ACCESS_MASM(masm_)
#ifdef DEBUG
@@ -188,21 +224,6 @@ void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) {
}
-bool CodeGenerator::ShouldGenerateLog(Isolate* isolate, Expression* type) {
- ASSERT(type != NULL);
- if (!isolate->logger()->is_logging() &&
- !isolate->cpu_profiler()->is_profiling()) {
- return false;
- }
- Handle<String> name = Handle<String>::cast(type->AsLiteral()->value());
- if (FLAG_log_regexp) {
- if (name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("regexp")))
- return true;
- }
- return false;
-}
-
-
bool CodeGenerator::RecordPositions(MacroAssembler* masm,
int pos,
bool right_here) {
diff --git a/deps/v8/src/codegen.h b/deps/v8/src/codegen.h
index 6b5f9513ea..fbaee97c8f 100644
--- a/deps/v8/src/codegen.h
+++ b/deps/v8/src/codegen.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_CODEGEN_H_
#define V8_CODEGEN_H_
@@ -102,8 +79,6 @@ class CodeGenerator {
// Print the code after compiling it.
static void PrintCode(Handle<Code> code, CompilationInfo* info);
- static bool ShouldGenerateLog(Isolate* isolate, Expression* type);
-
static bool RecordPositions(MacroAssembler* masm,
int pos,
bool right_here = false);
@@ -122,6 +97,18 @@ UnaryMathFunction CreateExpFunction();
UnaryMathFunction CreateSqrtFunction();
+double modulo(double x, double y);
+
+// Custom implementation of math functions.
+double fast_exp(double input);
+double fast_sqrt(double input);
+#ifdef _WIN64
+void init_modulo_function();
+#endif
+void lazily_initialize_fast_exp();
+void init_fast_sqrt_function();
+
+
class ElementsTransitionGenerator : public AllStatic {
public:
// If |mode| is set to DONT_TRACK_ALLOCATION_SITE,
@@ -143,6 +130,33 @@ class ElementsTransitionGenerator : public AllStatic {
static const int kNumberDictionaryProbes = 4;
+class CodeAgingHelper {
+ public:
+ CodeAgingHelper();
+
+ uint32_t young_sequence_length() const { return young_sequence_.length(); }
+ bool IsYoung(byte* candidate) const {
+ return memcmp(candidate,
+ young_sequence_.start(),
+ young_sequence_.length()) == 0;
+ }
+ void CopyYoungSequenceTo(byte* new_buffer) const {
+ CopyBytes(new_buffer, young_sequence_.start(), young_sequence_.length());
+ }
+
+#ifdef DEBUG
+ bool IsOld(byte* candidate) const;
+#endif
+
+ protected:
+ const EmbeddedVector<byte, kNoCodeAgeSequenceLength> young_sequence_;
+#ifdef DEBUG
+#ifdef V8_TARGET_ARCH_ARM64
+ const EmbeddedVector<byte, kNoCodeAgeSequenceLength> old_sequence_;
+#endif
+#endif
+};
+
} } // namespace v8::internal
#endif // V8_CODEGEN_H_
diff --git a/deps/v8/src/collection.js b/deps/v8/src/collection.js
index 9054187a12..f8f3fa995c 100644
--- a/deps/v8/src/collection.js
+++ b/deps/v8/src/collection.js
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
"use strict";
@@ -113,8 +90,29 @@ function SetClear() {
throw MakeTypeError('incompatible_method_receiver',
['Set.prototype.clear', this]);
}
- // Replace the internal table with a new empty table.
- %SetInitialize(this);
+ %SetClear(this);
+}
+
+
+function SetForEach(f, receiver) {
+ if (!IS_SET(this)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['Set.prototype.forEach', this]);
+ }
+
+ if (!IS_SPEC_FUNCTION(f)) {
+ throw MakeTypeError('called_non_callable', [f]);
+ }
+
+ var iterator = %SetCreateIterator(this, ITERATOR_KIND_VALUES);
+ var entry;
+ try {
+ while (!(entry = %SetIteratorNext(iterator)).done) {
+ %_CallFunction(receiver, entry.value, entry.value, this, f);
+ }
+ } finally {
+ %SetIteratorClose(iterator);
+ }
}
@@ -127,13 +125,16 @@ function SetUpSet() {
%FunctionSetPrototype($Set, new $Object());
%SetProperty($Set.prototype, "constructor", $Set, DONT_ENUM);
+ %FunctionSetLength(SetForEach, 1);
+
// Set up the non-enumerable functions on the Set prototype object.
InstallGetter($Set.prototype, "size", SetGetSize);
InstallFunctions($Set.prototype, DONT_ENUM, $Array(
"add", SetAdd,
"has", SetHas,
"delete", SetDelete,
- "clear", SetClear
+ "clear", SetClear,
+ "forEach", SetForEach
));
}
@@ -202,8 +203,29 @@ function MapClear() {
throw MakeTypeError('incompatible_method_receiver',
['Map.prototype.clear', this]);
}
- // Replace the internal table with a new empty table.
- %MapInitialize(this);
+ %MapClear(this);
+}
+
+
+function MapForEach(f, receiver) {
+ if (!IS_MAP(this)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['Map.prototype.forEach', this]);
+ }
+
+ if (!IS_SPEC_FUNCTION(f)) {
+ throw MakeTypeError('called_non_callable', [f]);
+ }
+
+ var iterator = %MapCreateIterator(this, ITERATOR_KIND_ENTRIES);
+ var entry;
+ try {
+ while (!(entry = %MapIteratorNext(iterator)).done) {
+ %_CallFunction(receiver, entry.value[1], entry.value[0], this, f);
+ }
+ } finally {
+ %MapIteratorClose(iterator);
+ }
}
@@ -216,6 +238,8 @@ function SetUpMap() {
%FunctionSetPrototype($Map, new $Object());
%SetProperty($Map.prototype, "constructor", $Map, DONT_ENUM);
+ %FunctionSetLength(MapForEach, 1);
+
// Set up the non-enumerable functions on the Map prototype object.
InstallGetter($Map.prototype, "size", MapGetSize);
InstallFunctions($Map.prototype, DONT_ENUM, $Array(
@@ -223,7 +247,8 @@ function SetUpMap() {
"set", MapSet,
"has", MapHas,
"delete", MapDelete,
- "clear", MapClear
+ "clear", MapClear,
+ "forEach", MapForEach
));
}
diff --git a/deps/v8/src/compilation-cache.cc b/deps/v8/src/compilation-cache.cc
index 54d4565e2d..42a94fc74f 100644
--- a/deps/v8/src/compilation-cache.cc
+++ b/deps/v8/src/compilation-cache.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -65,18 +42,11 @@ CompilationCache::CompilationCache(Isolate* isolate)
CompilationCache::~CompilationCache() {}
-static Handle<CompilationCacheTable> AllocateTable(Isolate* isolate, int size) {
- CALL_HEAP_FUNCTION(isolate,
- CompilationCacheTable::Allocate(isolate->heap(), size),
- CompilationCacheTable);
-}
-
-
Handle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) {
ASSERT(generation < generations_);
Handle<CompilationCacheTable> result;
if (tables_[generation]->IsUndefined()) {
- result = AllocateTable(isolate(), kInitialCacheSize);
+ result = CompilationCacheTable::New(isolate(), kInitialCacheSize);
tables_[generation] = *result;
} else {
CompilationCacheTable* table =
@@ -161,7 +131,8 @@ bool CompilationCacheScript::HasOrigin(
// Were both scripts tagged by the embedder as being shared cross-origin?
if (is_shared_cross_origin != script->is_shared_cross_origin()) return false;
// Compare the two name strings for equality.
- return String::cast(*name)->Equals(String::cast(script->name()));
+ return String::Equals(Handle<String>::cast(name),
+ Handle<String>(String::cast(script->name())));
}
@@ -184,7 +155,7 @@ Handle<SharedFunctionInfo> CompilationCacheScript::Lookup(
{ HandleScope scope(isolate());
for (generation = 0; generation < generations(); generation++) {
Handle<CompilationCacheTable> table = GetTable(generation);
- Handle<Object> probe(table->Lookup(*source, *context), isolate());
+ Handle<Object> probe = table->Lookup(source, context);
if (probe->IsSharedFunctionInfo()) {
Handle<SharedFunctionInfo> function_info =
Handle<SharedFunctionInfo>::cast(probe);
@@ -239,153 +210,93 @@ Handle<SharedFunctionInfo> CompilationCacheScript::Lookup(
}
-MaybeObject* CompilationCacheScript::TryTablePut(
- Handle<String> source,
- Handle<Context> context,
- Handle<SharedFunctionInfo> function_info) {
- Handle<CompilationCacheTable> table = GetFirstTable();
- return table->Put(*source, *context, *function_info);
-}
-
-
-Handle<CompilationCacheTable> CompilationCacheScript::TablePut(
- Handle<String> source,
- Handle<Context> context,
- Handle<SharedFunctionInfo> function_info) {
- CALL_HEAP_FUNCTION(isolate(),
- TryTablePut(source, context, function_info),
- CompilationCacheTable);
-}
-
-
void CompilationCacheScript::Put(Handle<String> source,
Handle<Context> context,
Handle<SharedFunctionInfo> function_info) {
HandleScope scope(isolate());
- SetFirstTable(TablePut(source, context, function_info));
+ Handle<CompilationCacheTable> table = GetFirstTable();
+ SetFirstTable(
+ CompilationCacheTable::Put(table, source, context, function_info));
}
-Handle<SharedFunctionInfo> CompilationCacheEval::Lookup(
+MaybeHandle<SharedFunctionInfo> CompilationCacheEval::Lookup(
Handle<String> source,
Handle<Context> context,
StrictMode strict_mode,
int scope_position) {
+ HandleScope scope(isolate());
// Make sure not to leak the table into the surrounding handle
// scope. Otherwise, we risk keeping old tables around even after
// having cleared the cache.
- Object* result = NULL;
+ Handle<Object> result = isolate()->factory()->undefined_value();
int generation;
- { HandleScope scope(isolate());
- for (generation = 0; generation < generations(); generation++) {
- Handle<CompilationCacheTable> table = GetTable(generation);
- result = table->LookupEval(
- *source, *context, strict_mode, scope_position);
- if (result->IsSharedFunctionInfo()) {
- break;
- }
- }
+ for (generation = 0; generation < generations(); generation++) {
+ Handle<CompilationCacheTable> table = GetTable(generation);
+ result = table->LookupEval(source, context, strict_mode, scope_position);
+ if (result->IsSharedFunctionInfo()) break;
}
if (result->IsSharedFunctionInfo()) {
- Handle<SharedFunctionInfo>
- function_info(SharedFunctionInfo::cast(result), isolate());
+ Handle<SharedFunctionInfo> function_info =
+ Handle<SharedFunctionInfo>::cast(result);
if (generation != 0) {
Put(source, context, function_info, scope_position);
}
isolate()->counters()->compilation_cache_hits()->Increment();
- return function_info;
+ return scope.CloseAndEscape(function_info);
} else {
isolate()->counters()->compilation_cache_misses()->Increment();
- return Handle<SharedFunctionInfo>::null();
+ return MaybeHandle<SharedFunctionInfo>();
}
}
-MaybeObject* CompilationCacheEval::TryTablePut(
- Handle<String> source,
- Handle<Context> context,
- Handle<SharedFunctionInfo> function_info,
- int scope_position) {
- Handle<CompilationCacheTable> table = GetFirstTable();
- return table->PutEval(*source, *context, *function_info, scope_position);
-}
-
-
-Handle<CompilationCacheTable> CompilationCacheEval::TablePut(
- Handle<String> source,
- Handle<Context> context,
- Handle<SharedFunctionInfo> function_info,
- int scope_position) {
- CALL_HEAP_FUNCTION(isolate(),
- TryTablePut(
- source, context, function_info, scope_position),
- CompilationCacheTable);
-}
-
-
void CompilationCacheEval::Put(Handle<String> source,
Handle<Context> context,
Handle<SharedFunctionInfo> function_info,
int scope_position) {
HandleScope scope(isolate());
- SetFirstTable(TablePut(source, context, function_info, scope_position));
+ Handle<CompilationCacheTable> table = GetFirstTable();
+ table = CompilationCacheTable::PutEval(table, source, context,
+ function_info, scope_position);
+ SetFirstTable(table);
}
-Handle<FixedArray> CompilationCacheRegExp::Lookup(Handle<String> source,
- JSRegExp::Flags flags) {
+MaybeHandle<FixedArray> CompilationCacheRegExp::Lookup(
+ Handle<String> source,
+ JSRegExp::Flags flags) {
+ HandleScope scope(isolate());
// Make sure not to leak the table into the surrounding handle
// scope. Otherwise, we risk keeping old tables around even after
// having cleared the cache.
- Object* result = NULL;
+ Handle<Object> result = isolate()->factory()->undefined_value();
int generation;
- { HandleScope scope(isolate());
- for (generation = 0; generation < generations(); generation++) {
- Handle<CompilationCacheTable> table = GetTable(generation);
- result = table->LookupRegExp(*source, flags);
- if (result->IsFixedArray()) {
- break;
- }
- }
+ for (generation = 0; generation < generations(); generation++) {
+ Handle<CompilationCacheTable> table = GetTable(generation);
+ result = table->LookupRegExp(source, flags);
+ if (result->IsFixedArray()) break;
}
if (result->IsFixedArray()) {
- Handle<FixedArray> data(FixedArray::cast(result), isolate());
+ Handle<FixedArray> data = Handle<FixedArray>::cast(result);
if (generation != 0) {
Put(source, flags, data);
}
isolate()->counters()->compilation_cache_hits()->Increment();
- return data;
+ return scope.CloseAndEscape(data);
} else {
isolate()->counters()->compilation_cache_misses()->Increment();
- return Handle<FixedArray>::null();
+ return MaybeHandle<FixedArray>();
}
}
-MaybeObject* CompilationCacheRegExp::TryTablePut(
- Handle<String> source,
- JSRegExp::Flags flags,
- Handle<FixedArray> data) {
- Handle<CompilationCacheTable> table = GetFirstTable();
- return table->PutRegExp(*source, flags, *data);
-}
-
-
-Handle<CompilationCacheTable> CompilationCacheRegExp::TablePut(
- Handle<String> source,
- JSRegExp::Flags flags,
- Handle<FixedArray> data) {
- CALL_HEAP_FUNCTION(isolate(),
- TryTablePut(source, flags, data),
- CompilationCacheTable);
-}
-
-
void CompilationCacheRegExp::Put(Handle<String> source,
JSRegExp::Flags flags,
Handle<FixedArray> data) {
HandleScope scope(isolate());
- SetFirstTable(TablePut(source, flags, data));
+ Handle<CompilationCacheTable> table = GetFirstTable();
+ SetFirstTable(CompilationCacheTable::PutRegExp(table, source, flags, data));
}
@@ -398,36 +309,28 @@ void CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) {
}
-Handle<SharedFunctionInfo> CompilationCache::LookupScript(
+MaybeHandle<SharedFunctionInfo> CompilationCache::LookupScript(
Handle<String> source,
Handle<Object> name,
int line_offset,
int column_offset,
bool is_shared_cross_origin,
Handle<Context> context) {
- if (!IsEnabled()) {
- return Handle<SharedFunctionInfo>::null();
- }
+ if (!IsEnabled()) return MaybeHandle<SharedFunctionInfo>();
- return script_.Lookup(source,
- name,
- line_offset,
- column_offset,
- is_shared_cross_origin,
- context);
+ return script_.Lookup(source, name, line_offset, column_offset,
+ is_shared_cross_origin, context);
}
-Handle<SharedFunctionInfo> CompilationCache::LookupEval(
+MaybeHandle<SharedFunctionInfo> CompilationCache::LookupEval(
Handle<String> source,
Handle<Context> context,
StrictMode strict_mode,
int scope_position) {
- if (!IsEnabled()) {
- return Handle<SharedFunctionInfo>::null();
- }
+ if (!IsEnabled()) return MaybeHandle<SharedFunctionInfo>();
- Handle<SharedFunctionInfo> result;
+ MaybeHandle<SharedFunctionInfo> result;
if (context->IsNativeContext()) {
result = eval_global_.Lookup(
source, context, strict_mode, scope_position);
@@ -440,11 +343,9 @@ Handle<SharedFunctionInfo> CompilationCache::LookupEval(
}
-Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
+MaybeHandle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
JSRegExp::Flags flags) {
- if (!IsEnabled()) {
- return Handle<FixedArray>::null();
- }
+ if (!IsEnabled()) return MaybeHandle<FixedArray>();
return reg_exp_.Lookup(source, flags);
}
diff --git a/deps/v8/src/compilation-cache.h b/deps/v8/src/compilation-cache.h
index b31de3111f..baa53fb45d 100644
--- a/deps/v8/src/compilation-cache.h
+++ b/deps/v8/src/compilation-cache.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_COMPILATION_CACHE_H_
#define V8_COMPILATION_CACHE_H_
@@ -106,17 +83,6 @@ class CompilationCacheScript : public CompilationSubCache {
Handle<SharedFunctionInfo> function_info);
private:
- MUST_USE_RESULT MaybeObject* TryTablePut(
- Handle<String> source,
- Handle<Context> context,
- Handle<SharedFunctionInfo> function_info);
-
- // Note: Returns a new hash table if operation results in expansion.
- Handle<CompilationCacheTable> TablePut(
- Handle<String> source,
- Handle<Context> context,
- Handle<SharedFunctionInfo> function_info);
-
bool HasOrigin(Handle<SharedFunctionInfo> function_info,
Handle<Object> name,
int line_offset,
@@ -147,10 +113,10 @@ class CompilationCacheEval: public CompilationSubCache {
CompilationCacheEval(Isolate* isolate, int generations)
: CompilationSubCache(isolate, generations) { }
- Handle<SharedFunctionInfo> Lookup(Handle<String> source,
- Handle<Context> context,
- StrictMode strict_mode,
- int scope_position);
+ MaybeHandle<SharedFunctionInfo> Lookup(Handle<String> source,
+ Handle<Context> context,
+ StrictMode strict_mode,
+ int scope_position);
void Put(Handle<String> source,
Handle<Context> context,
@@ -158,19 +124,6 @@ class CompilationCacheEval: public CompilationSubCache {
int scope_position);
private:
- MUST_USE_RESULT MaybeObject* TryTablePut(
- Handle<String> source,
- Handle<Context> context,
- Handle<SharedFunctionInfo> function_info,
- int scope_position);
-
- // Note: Returns a new hash table if operation results in expansion.
- Handle<CompilationCacheTable> TablePut(
- Handle<String> source,
- Handle<Context> context,
- Handle<SharedFunctionInfo> function_info,
- int scope_position);
-
DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval);
};
@@ -181,21 +134,12 @@ class CompilationCacheRegExp: public CompilationSubCache {
CompilationCacheRegExp(Isolate* isolate, int generations)
: CompilationSubCache(isolate, generations) { }
- Handle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags);
+ MaybeHandle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags);
void Put(Handle<String> source,
JSRegExp::Flags flags,
Handle<FixedArray> data);
private:
- MUST_USE_RESULT MaybeObject* TryTablePut(Handle<String> source,
- JSRegExp::Flags flags,
- Handle<FixedArray> data);
-
- // Note: Returns a new hash table if operation results in expansion.
- Handle<CompilationCacheTable> TablePut(Handle<String> source,
- JSRegExp::Flags flags,
- Handle<FixedArray> data);
-
DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp);
};
@@ -209,25 +153,21 @@ class CompilationCache {
// Finds the script shared function info for a source
// string. Returns an empty handle if the cache doesn't contain a
// script for the given source string with the right origin.
- Handle<SharedFunctionInfo> LookupScript(Handle<String> source,
- Handle<Object> name,
- int line_offset,
- int column_offset,
- bool is_shared_cross_origin,
- Handle<Context> context);
+ MaybeHandle<SharedFunctionInfo> LookupScript(
+ Handle<String> source, Handle<Object> name, int line_offset,
+ int column_offset, bool is_shared_cross_origin, Handle<Context> context);
// Finds the shared function info for a source string for eval in a
// given context. Returns an empty handle if the cache doesn't
// contain a script for the given source string.
- Handle<SharedFunctionInfo> LookupEval(Handle<String> source,
- Handle<Context> context,
- StrictMode strict_mode,
- int scope_position);
+ MaybeHandle<SharedFunctionInfo> LookupEval(
+ Handle<String> source, Handle<Context> context, StrictMode strict_mode,
+ int scope_position);
// Returns the regexp data associated with the given regexp if it
// is in cache, otherwise an empty handle.
- Handle<FixedArray> LookupRegExp(Handle<String> source,
- JSRegExp::Flags flags);
+ MaybeHandle<FixedArray> LookupRegExp(
+ Handle<String> source, JSRegExp::Flags flags);
// Associate the (source, kind) pair to the shared function
// info. This may overwrite an existing mapping.
diff --git a/deps/v8/src/compiler-intrinsics.h b/deps/v8/src/compiler-intrinsics.h
index b73e8ac750..f31895e2d3 100644
--- a/deps/v8/src/compiler-intrinsics.h
+++ b/deps/v8/src/compiler-intrinsics.h
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_COMPILER_INTRINSICS_H_
#define V8_COMPILER_INTRINSICS_H_
diff --git a/deps/v8/src/compiler.cc b/deps/v8/src/compiler.cc
index 4b539897b8..7b9f705bc3 100644
--- a/deps/v8/src/compiler.cc
+++ b/deps/v8/src/compiler.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -141,6 +118,13 @@ void CompilationInfo::Initialize(Isolate* isolate,
SetStrictMode(shared_info_->strict_mode());
}
set_bailout_reason(kUnknown);
+
+ if (!shared_info().is_null() && shared_info()->is_compiled()) {
+ // We should initialize the CompilationInfo feedback vector from the
+ // passed in shared info, rather than creating a new one.
+ feedback_vector_ = Handle<FixedArray>(shared_info()->feedback_vector(),
+ isolate);
+ }
}
@@ -249,7 +233,13 @@ bool CompilationInfo::ShouldSelfOptimize() {
void CompilationInfo::PrepareForCompilation(Scope* scope) {
ASSERT(scope_ == NULL);
scope_ = scope;
- function()->ProcessFeedbackSlots(isolate_);
+
+ int length = function()->slot_count();
+ if (feedback_vector_.is_null()) {
+ // Allocate the feedback vector too.
+ feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector(length);
+ }
+ ASSERT(feedback_vector_->length() == length);
}
@@ -298,13 +288,9 @@ class HOptimizedGraphBuilderWithPositions: public HOptimizedGraphBuilder {
// the full compiler need not be be used if a debugger is attached, but only if
// break points has actually been set.
static bool IsDebuggerActive(Isolate* isolate) {
-#ifdef ENABLE_DEBUGGER_SUPPORT
return isolate->use_crankshaft() ?
isolate->debug()->has_break_points() :
isolate->debugger()->IsDebuggerActive();
-#else
- return false;
-#endif
}
@@ -354,6 +340,10 @@ OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() {
return AbortAndDisableOptimization(kTooManyParametersLocals);
}
+ if (scope->HasIllegalRedeclaration()) {
+ return AbortAndDisableOptimization(kFunctionWithIllegalRedeclaration);
+ }
+
// Take --hydrogen-filter into account.
if (!info()->closure()->PassesFilter(FLAG_hydrogen_filter)) {
return AbortOptimization(kHydrogenFilter);
@@ -541,7 +531,7 @@ void SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo> shared,
// TODO(yangguo): check whether those heuristics are still up-to-date.
// We do not shrink objects that go into a snapshot (yet), so we adjust
// the estimate conservatively.
- if (Serializer::enabled()) {
+ if (Serializer::enabled(shared->GetIsolate())) {
estimate += 2;
} else if (FLAG_clever_optimizations) {
// Inobject slack tracking will reclaim redundant inobject space later,
@@ -571,6 +561,8 @@ static void UpdateSharedFunctionInfo(CompilationInfo* info) {
shared->ReplaceCode(*code);
if (shared->optimization_disabled()) code->set_optimizable(false);
+ shared->set_feedback_vector(*info->feedback_vector());
+
// Set the expected number of properties for instances.
FunctionLiteral* lit = info->function();
int expected = lit->expected_property_count();
@@ -633,13 +625,14 @@ static bool CompileUnoptimizedCode(CompilationInfo* info) {
}
-static Handle<Code> GetUnoptimizedCodeCommon(CompilationInfo* info) {
+MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon(
+ CompilationInfo* info) {
VMState<COMPILER> state(info->isolate());
PostponeInterruptsScope postpone(info->isolate());
- if (!Parser::Parse(info)) return Handle<Code>::null();
+ if (!Parser::Parse(info)) return MaybeHandle<Code>();
info->SetStrictMode(info->function()->strict_mode());
- if (!CompileUnoptimizedCode(info)) return Handle<Code>::null();
+ if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>();
Compiler::RecordFunctionCompilation(
Logger::LAZY_COMPILE_TAG, info, info->shared_info());
UpdateSharedFunctionInfo(info);
@@ -648,7 +641,7 @@ static Handle<Code> GetUnoptimizedCodeCommon(CompilationInfo* info) {
}
-Handle<Code> Compiler::GetUnoptimizedCode(Handle<JSFunction> function) {
+MaybeHandle<Code> Compiler::GetUnoptimizedCode(Handle<JSFunction> function) {
ASSERT(!function->GetIsolate()->has_pending_exception());
ASSERT(!function->is_compiled());
if (function->shared()->is_compiled()) {
@@ -656,39 +649,43 @@ Handle<Code> Compiler::GetUnoptimizedCode(Handle<JSFunction> function) {
}
CompilationInfoWithZone info(function);
- Handle<Code> result = GetUnoptimizedCodeCommon(&info);
- ASSERT_EQ(result.is_null(), info.isolate()->has_pending_exception());
+ Handle<Code> result;
+ ASSIGN_RETURN_ON_EXCEPTION(info.isolate(), result,
+ GetUnoptimizedCodeCommon(&info),
+ Code);
if (FLAG_always_opt &&
- !result.is_null() &&
info.isolate()->use_crankshaft() &&
!info.shared_info()->optimization_disabled() &&
!info.isolate()->DebuggerHasBreakPoints()) {
- Handle<Code> opt_code = Compiler::GetOptimizedCode(
- function, result, Compiler::NOT_CONCURRENT);
- if (!opt_code.is_null()) result = opt_code;
+ Handle<Code> opt_code;
+ if (Compiler::GetOptimizedCode(
+ function, result,
+ Compiler::NOT_CONCURRENT).ToHandle(&opt_code)) {
+ result = opt_code;
+ }
}
return result;
}
-Handle<Code> Compiler::GetUnoptimizedCode(Handle<SharedFunctionInfo> shared) {
+MaybeHandle<Code> Compiler::GetUnoptimizedCode(
+ Handle<SharedFunctionInfo> shared) {
ASSERT(!shared->GetIsolate()->has_pending_exception());
ASSERT(!shared->is_compiled());
CompilationInfoWithZone info(shared);
- Handle<Code> result = GetUnoptimizedCodeCommon(&info);
- ASSERT_EQ(result.is_null(), info.isolate()->has_pending_exception());
- return result;
+ return GetUnoptimizedCodeCommon(&info);
}
bool Compiler::EnsureCompiled(Handle<JSFunction> function,
ClearExceptionFlag flag) {
if (function->is_compiled()) return true;
- Handle<Code> code = Compiler::GetUnoptimizedCode(function);
- if (code.is_null()) {
+ MaybeHandle<Code> maybe_code = Compiler::GetUnoptimizedCode(function);
+ Handle<Code> code;
+ if (!maybe_code.ToHandle(&code)) {
if (flag == CLEAR_EXCEPTION) {
function->GetIsolate()->clear_pending_exception();
}
@@ -709,7 +706,7 @@ bool Compiler::EnsureCompiled(Handle<JSFunction> function,
// full code without debug break slots to full code with debug break slots
// depends on the generated code is otherwise exactly the same.
// If compilation fails, just keep the existing code.
-Handle<Code> Compiler::GetCodeForDebugging(Handle<JSFunction> function) {
+MaybeHandle<Code> Compiler::GetCodeForDebugging(Handle<JSFunction> function) {
CompilationInfoWithZone info(function);
Isolate* isolate = info.isolate();
VMState<COMPILER> state(isolate);
@@ -725,18 +722,18 @@ Handle<Code> Compiler::GetCodeForDebugging(Handle<JSFunction> function) {
} else {
info.MarkNonOptimizable();
}
- Handle<Code> new_code = GetUnoptimizedCodeCommon(&info);
- if (new_code.is_null()) {
+ MaybeHandle<Code> maybe_new_code = GetUnoptimizedCodeCommon(&info);
+ Handle<Code> new_code;
+ if (!maybe_new_code.ToHandle(&new_code)) {
isolate->clear_pending_exception();
} else {
ASSERT_EQ(old_code->is_compiled_optimizable(),
new_code->is_compiled_optimizable());
}
- return new_code;
+ return maybe_new_code;
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
void Compiler::CompileForLiveEdit(Handle<Script> script) {
// TODO(635): support extensions.
CompilationInfoWithZone info(script);
@@ -756,7 +753,6 @@ void Compiler::CompileForLiveEdit(Handle<Script> script) {
}
tracker.RecordRootFunctionInfo(info.code());
}
-#endif
static bool DebuggerWantsEagerCompilation(CompilationInfo* info,
@@ -776,9 +772,7 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
FixedArray* array = isolate->native_context()->embedder_data();
script->set_context_data(array->get(0));
-#ifdef ENABLE_DEBUGGER_SUPPORT
isolate->debugger()->OnBeforeCompile(script);
-#endif
ASSERT(info->is_eval() || info->is_global());
@@ -827,7 +821,8 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
lit->materialized_literal_count(),
lit->is_generator(),
info->code(),
- ScopeInfo::Create(info->scope(), info->zone()));
+ ScopeInfo::Create(info->scope(), info->zone()),
+ info->feedback_vector());
ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
SetFunctionInfo(result, lit, true, script);
@@ -854,29 +849,30 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
live_edit_tracker.RecordFunctionInfo(result, lit, info->zone());
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
isolate->debugger()->OnAfterCompile(script, Debugger::NO_AFTER_COMPILE_FLAGS);
-#endif
return result;
}
-Handle<JSFunction> Compiler::GetFunctionFromEval(Handle<String> source,
- Handle<Context> context,
- StrictMode strict_mode,
- ParseRestriction restriction,
- int scope_position) {
+MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
+ Handle<String> source,
+ Handle<Context> context,
+ StrictMode strict_mode,
+ ParseRestriction restriction,
+ int scope_position) {
Isolate* isolate = source->GetIsolate();
int source_length = source->length();
isolate->counters()->total_eval_size()->Increment(source_length);
isolate->counters()->total_compile_size()->Increment(source_length);
CompilationCache* compilation_cache = isolate->compilation_cache();
- Handle<SharedFunctionInfo> shared_info = compilation_cache->LookupEval(
- source, context, strict_mode, scope_position);
+ MaybeHandle<SharedFunctionInfo> maybe_shared_info =
+ compilation_cache->LookupEval(source, context, strict_mode,
+ scope_position);
+ Handle<SharedFunctionInfo> shared_info;
- if (shared_info.is_null()) {
+ if (!maybe_shared_info.ToHandle(&shared_info)) {
Handle<Script> script = isolate->factory()->NewScript(source);
CompilationInfoWithZone info(script);
info.MarkAsEval();
@@ -885,14 +881,12 @@ Handle<JSFunction> Compiler::GetFunctionFromEval(Handle<String> source,
info.SetParseRestriction(restriction);
info.SetContext(context);
-#if ENABLE_DEBUGGER_SUPPORT
Debug::RecordEvalCaller(script);
-#endif // ENABLE_DEBUGGER_SUPPORT
shared_info = CompileToplevel(&info);
if (shared_info.is_null()) {
- return Handle<JSFunction>::null();
+ return MaybeHandle<JSFunction>();
} else {
// Explicitly disable optimization for eval code. We're not yet prepared
// to handle eval-code in the optimizing compiler.
@@ -922,7 +916,7 @@ Handle<SharedFunctionInfo> Compiler::CompileScript(
bool is_shared_cross_origin,
Handle<Context> context,
v8::Extension* extension,
- ScriptDataImpl** cached_data,
+ ScriptData** cached_data,
CachedDataMode cached_data_mode,
NativesFlag natives) {
if (cached_data_mode == NO_CACHED_DATA) {
@@ -941,25 +935,16 @@ Handle<SharedFunctionInfo> Compiler::CompileScript(
CompilationCache* compilation_cache = isolate->compilation_cache();
// Do a lookup in the compilation cache but not for extensions.
+ MaybeHandle<SharedFunctionInfo> maybe_result;
Handle<SharedFunctionInfo> result;
if (extension == NULL) {
- result = compilation_cache->LookupScript(source,
- script_name,
- line_offset,
- column_offset,
- is_shared_cross_origin,
- context);
+ maybe_result = compilation_cache->LookupScript(
+ source, script_name, line_offset, column_offset,
+ is_shared_cross_origin, context);
}
- if (result.is_null()) {
- // No cache entry found. Do pre-parsing, if it makes sense, and compile
- // the script.
- // Building preparse data that is only used immediately after is only a
- // saving if we might skip building the AST for lazily compiled functions.
- // I.e., preparse data isn't relevant when the lazy flag is off, and
- // for small sources, odds are that there aren't many functions
- // that would be compiled lazily anyway, so we skip the preparse step
- // in that case too.
+ if (!maybe_result.ToHandle(&result)) {
+ // No cache entry found. Compile the script.
// Create a script object describing the script to be compiled.
Handle<Script> script = isolate->factory()->NewScript(source);
@@ -984,11 +969,10 @@ Handle<SharedFunctionInfo> Compiler::CompileScript(
if (extension == NULL && !result.is_null() && !result->dont_cache()) {
compilation_cache->PutScript(source, context, result);
}
+ if (result.is_null()) isolate->ReportPendingMessages();
} else if (result->ic_age() != isolate->heap()->global_ic_age()) {
result->ResetForNewContext(isolate->heap()->global_ic_age());
}
-
- if (result.is_null()) isolate->ReportPendingMessages();
return result;
}
@@ -1036,7 +1020,8 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
literal->materialized_literal_count(),
literal->is_generator(),
info.code(),
- scope_info);
+ scope_info,
+ info.feedback_vector());
SetFunctionInfo(result, literal, false, script);
RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result);
result->set_allows_lazy_compilation(allow_lazy);
@@ -1051,8 +1036,9 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
}
-static Handle<Code> GetCodeFromOptimizedCodeMap(Handle<JSFunction> function,
- BailoutId osr_ast_id) {
+MUST_USE_RESULT static MaybeHandle<Code> GetCodeFromOptimizedCodeMap(
+ Handle<JSFunction> function,
+ BailoutId osr_ast_id) {
if (FLAG_cache_optimized_code) {
Handle<SharedFunctionInfo> shared(function->shared());
DisallowHeapAllocation no_gc;
@@ -1072,7 +1058,7 @@ static Handle<Code> GetCodeFromOptimizedCodeMap(Handle<JSFunction> function,
return Handle<Code>(shared->GetCodeFromOptimizedCodeMap(index));
}
}
- return Handle<Code>::null();
+ return MaybeHandle<Code>();
}
@@ -1159,12 +1145,15 @@ static bool GetOptimizedCodeLater(CompilationInfo* info) {
}
-Handle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function,
- Handle<Code> current_code,
- ConcurrencyMode mode,
- BailoutId osr_ast_id) {
- Handle<Code> cached_code = GetCodeFromOptimizedCodeMap(function, osr_ast_id);
- if (!cached_code.is_null()) return cached_code;
+MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function,
+ Handle<Code> current_code,
+ ConcurrencyMode mode,
+ BailoutId osr_ast_id) {
+ Handle<Code> cached_code;
+ if (GetCodeFromOptimizedCodeMap(
+ function, osr_ast_id).ToHandle(&cached_code)) {
+ return cached_code;
+ }
SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(function));
Isolate* isolate = info->isolate();
@@ -1197,7 +1186,7 @@ Handle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function,
}
if (isolate->has_pending_exception()) isolate->clear_pending_exception();
- return Handle<Code>::null();
+ return MaybeHandle<Code>();
}
@@ -1261,12 +1250,13 @@ void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag,
info->isolate()->cpu_profiler()->is_profiling()) {
Handle<Script> script = info->script();
Handle<Code> code = info->code();
- if (code.is_identical_to(info->isolate()->builtins()->CompileUnoptimized()))
+ if (code.is_identical_to(
+ info->isolate()->builtins()->CompileUnoptimized())) {
return;
- int line_num = GetScriptLineNumber(script, shared->start_position()) + 1;
+ }
+ int line_num = Script::GetLineNumber(script, shared->start_position()) + 1;
int column_num =
- GetScriptColumnNumber(script, shared->start_position()) + 1;
- USE(line_num);
+ Script::GetColumnNumber(script, shared->start_position()) + 1;
String* script_name = script->name()->IsString()
? String::cast(script->name())
: info->isolate()->heap()->empty_string();
diff --git a/deps/v8/src/compiler.h b/deps/v8/src/compiler.h
index 3802016883..24a8a9f5de 100644
--- a/deps/v8/src/compiler.h
+++ b/deps/v8/src/compiler.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_COMPILER_H_
#define V8_COMPILER_H_
@@ -35,7 +12,7 @@
namespace v8 {
namespace internal {
-class ScriptDataImpl;
+class ScriptData;
class HydrogenCodeStub;
// ParseRestriction is used to restrict the set of valid statements in a
@@ -83,7 +60,7 @@ class CompilationInfo {
Handle<Script> script() const { return script_; }
HydrogenCodeStub* code_stub() const {return code_stub_; }
v8::Extension* extension() const { return extension_; }
- ScriptDataImpl** cached_data() const { return cached_data_; }
+ ScriptData** cached_data() const { return cached_data_; }
CachedDataMode cached_data_mode() const {
return cached_data_mode_;
}
@@ -178,18 +155,20 @@ class CompilationInfo {
ASSERT(function_ == NULL);
function_ = literal;
}
- // When the scope is applied, we may have deferred work to do on the function.
void PrepareForCompilation(Scope* scope);
void SetGlobalScope(Scope* global_scope) {
ASSERT(global_scope_ == NULL);
global_scope_ = global_scope;
}
+ Handle<FixedArray> feedback_vector() const {
+ return feedback_vector_;
+ }
void SetCode(Handle<Code> code) { code_ = code; }
void SetExtension(v8::Extension* extension) {
ASSERT(!is_lazy());
extension_ = extension;
}
- void SetCachedData(ScriptDataImpl** cached_data,
+ void SetCachedData(ScriptData** cached_data,
CachedDataMode cached_data_mode) {
cached_data_mode_ = cached_data_mode;
if (cached_data_mode == NO_CACHED_DATA) {
@@ -412,13 +391,16 @@ class CompilationInfo {
// Fields possibly needed for eager compilation, NULL by default.
v8::Extension* extension_;
- ScriptDataImpl** cached_data_;
+ ScriptData** cached_data_;
CachedDataMode cached_data_mode_;
// The context of the caller for eval code, and the global context for a
// global script. Will be a null handle otherwise.
Handle<Context> context_;
+ // Used by codegen, ultimately kept rooted by the SharedFunctionInfo.
+ Handle<FixedArray> feedback_vector_;
+
// Compilation mode flag and whether deoptimization is allowed.
Mode mode_;
BailoutId osr_ast_id_;
@@ -556,6 +538,8 @@ class OptimizedCompileJob: public ZoneObject {
MUST_USE_RESULT Status AbortAndDisableOptimization(
BailoutReason reason = kNoReason) {
if (reason != kNoReason) info_->set_bailout_reason(reason);
+ // Reference to shared function info does not change between phases.
+ AllowDeferredHandleDereference allow_handle_dereference;
info_->shared_info()->DisableOptimization(info_->bailout_reason());
return SetLastStatus(BAILED_OUT);
}
@@ -615,22 +599,24 @@ class OptimizedCompileJob: public ZoneObject {
class Compiler : public AllStatic {
public:
- static Handle<Code> GetUnoptimizedCode(Handle<JSFunction> function);
- static Handle<Code> GetUnoptimizedCode(Handle<SharedFunctionInfo> shared);
+ MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode(
+ Handle<JSFunction> function);
+ MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode(
+ Handle<SharedFunctionInfo> shared);
static bool EnsureCompiled(Handle<JSFunction> function,
ClearExceptionFlag flag);
- static Handle<Code> GetCodeForDebugging(Handle<JSFunction> function);
+ MUST_USE_RESULT static MaybeHandle<Code> GetCodeForDebugging(
+ Handle<JSFunction> function);
-#ifdef ENABLE_DEBUGGER_SUPPORT
static void CompileForLiveEdit(Handle<Script> script);
-#endif
// Compile a String source within a context for eval.
- static Handle<JSFunction> GetFunctionFromEval(Handle<String> source,
- Handle<Context> context,
- StrictMode strict_mode,
- ParseRestriction restriction,
- int scope_position);
+ MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval(
+ Handle<String> source,
+ Handle<Context> context,
+ StrictMode strict_mode,
+ ParseRestriction restriction,
+ int scope_position);
// Compile a String source within a context.
static Handle<SharedFunctionInfo> CompileScript(
@@ -641,7 +627,7 @@ class Compiler : public AllStatic {
bool is_shared_cross_origin,
Handle<Context> context,
v8::Extension* extension,
- ScriptDataImpl** cached_data,
+ ScriptData** cached_data,
CachedDataMode cached_data_mode,
NativesFlag is_natives_code);
@@ -654,7 +640,7 @@ class Compiler : public AllStatic {
// Generate and return optimized code or start a concurrent optimization job.
// In the latter case, return the InOptimizationQueue builtin. On failure,
// return the empty handle.
- static Handle<Code> GetOptimizedCode(
+ MUST_USE_RESULT static MaybeHandle<Code> GetOptimizedCode(
Handle<JSFunction> function,
Handle<Code> current_code,
ConcurrencyMode mode,
diff --git a/deps/v8/src/contexts.cc b/deps/v8/src/contexts.cc
index 33d47e9c4b..58ae49a9cc 100644
--- a/deps/v8/src/contexts.cc
+++ b/deps/v8/src/contexts.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -160,7 +137,8 @@ Handle<Object> Context::Lookup(Handle<String> name,
}
VariableMode mode;
InitializationFlag init_flag;
- int slot_index = scope_info->ContextSlotIndex(*name, &mode, &init_flag);
+ int slot_index =
+ ScopeInfo::ContextSlotIndex(scope_info, name, &mode, &init_flag);
ASSERT(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS);
if (slot_index >= 0) {
if (FLAG_trace_contexts) {
@@ -231,7 +209,7 @@ Handle<Object> Context::Lookup(Handle<String> name,
} else if (context->IsCatchContext()) {
// Catch contexts have the variable name in the extension slot.
- if (name->Equals(String::cast(context->extension()))) {
+ if (String::Equals(name, handle(String::cast(context->extension())))) {
if (FLAG_trace_contexts) {
PrintF("=> found in catch context\n");
}
@@ -365,11 +343,11 @@ Object* Context::DeoptimizedCodeListHead() {
Handle<Object> Context::ErrorMessageForCodeGenerationFromStrings() {
- Handle<Object> result(error_message_for_code_gen_from_strings(),
- GetIsolate());
+ Isolate* isolate = GetIsolate();
+ Handle<Object> result(error_message_for_code_gen_from_strings(), isolate);
if (!result->IsUndefined()) return result;
- return GetIsolate()->factory()->NewStringFromOneByte(STATIC_ASCII_VECTOR(
- "Code generation from strings disallowed for this context"));
+ return isolate->factory()->NewStringFromStaticAscii(
+ "Code generation from strings disallowed for this context");
}
diff --git a/deps/v8/src/contexts.h b/deps/v8/src/contexts.h
index 6ba9b3ed7d..f1aa380c76 100644
--- a/deps/v8/src/contexts.h
+++ b/deps/v8/src/contexts.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_CONTEXTS_H_
#define V8_CONTEXTS_H_
@@ -134,6 +111,16 @@ enum BindingFlags {
V(FLOAT32_ARRAY_FUN_INDEX, JSFunction, float32_array_fun) \
V(FLOAT64_ARRAY_FUN_INDEX, JSFunction, float64_array_fun) \
V(UINT8_CLAMPED_ARRAY_FUN_INDEX, JSFunction, uint8_clamped_array_fun) \
+ V(INT8_ARRAY_EXTERNAL_MAP_INDEX, Map, int8_array_external_map) \
+ V(UINT8_ARRAY_EXTERNAL_MAP_INDEX, Map, uint8_array_external_map) \
+ V(INT16_ARRAY_EXTERNAL_MAP_INDEX, Map, int16_array_external_map) \
+ V(UINT16_ARRAY_EXTERNAL_MAP_INDEX, Map, uint16_array_external_map) \
+ V(INT32_ARRAY_EXTERNAL_MAP_INDEX, Map, int32_array_external_map) \
+ V(UINT32_ARRAY_EXTERNAL_MAP_INDEX, Map, uint32_array_external_map) \
+ V(FLOAT32_ARRAY_EXTERNAL_MAP_INDEX, Map, float32_array_external_map) \
+ V(FLOAT64_ARRAY_EXTERNAL_MAP_INDEX, Map, float64_array_external_map) \
+ V(UINT8_CLAMPED_ARRAY_EXTERNAL_MAP_INDEX, Map, \
+ uint8_clamped_array_external_map) \
V(DATA_VIEW_FUN_INDEX, JSFunction, data_view_fun) \
V(SLOPPY_FUNCTION_MAP_INDEX, Map, sloppy_function_map) \
V(STRICT_FUNCTION_MAP_INDEX, Map, strict_function_map) \
@@ -168,7 +155,7 @@ enum BindingFlags {
V(ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX, Object, \
error_message_for_code_gen_from_strings) \
V(RUN_MICROTASKS_INDEX, JSFunction, run_microtasks) \
- V(ENQUEUE_EXTERNAL_MICROTASK_INDEX, JSFunction, enqueue_external_microtask) \
+ V(ENQUEUE_MICROTASK_INDEX, JSFunction, enqueue_microtask) \
V(IS_PROMISE_INDEX, JSFunction, is_promise) \
V(PROMISE_CREATE_INDEX, JSFunction, promise_create) \
V(PROMISE_RESOLVE_INDEX, JSFunction, promise_resolve) \
@@ -187,11 +174,19 @@ enum BindingFlags {
observers_begin_perform_splice) \
V(OBSERVERS_END_SPLICE_INDEX, JSFunction, \
observers_end_perform_splice) \
+ V(NATIVE_OBJECT_OBSERVE_INDEX, JSFunction, \
+ native_object_observe) \
+ V(NATIVE_OBJECT_GET_NOTIFIER_INDEX, JSFunction, \
+ native_object_get_notifier) \
+ V(NATIVE_OBJECT_NOTIFIER_PERFORM_CHANGE, JSFunction, \
+ native_object_notifier_perform_change) \
V(SLOPPY_GENERATOR_FUNCTION_MAP_INDEX, Map, sloppy_generator_function_map) \
V(STRICT_GENERATOR_FUNCTION_MAP_INDEX, Map, strict_generator_function_map) \
V(GENERATOR_OBJECT_PROTOTYPE_MAP_INDEX, Map, \
generator_object_prototype_map) \
- V(GENERATOR_RESULT_MAP_INDEX, Map, generator_result_map)
+ V(ITERATOR_RESULT_MAP_INDEX, Map, iterator_result_map) \
+ V(MAP_ITERATOR_MAP_INDEX, Map, map_iterator_map) \
+ V(SET_ITERATOR_MAP_INDEX, Map, set_iterator_map)
// JSFunctions are pairs (context, function code), sometimes also called
// closures. A Context object is used to represent function contexts and
@@ -309,6 +304,15 @@ class Context: public FixedArray {
FLOAT32_ARRAY_FUN_INDEX,
FLOAT64_ARRAY_FUN_INDEX,
UINT8_CLAMPED_ARRAY_FUN_INDEX,
+ INT8_ARRAY_EXTERNAL_MAP_INDEX,
+ UINT8_ARRAY_EXTERNAL_MAP_INDEX,
+ INT16_ARRAY_EXTERNAL_MAP_INDEX,
+ UINT16_ARRAY_EXTERNAL_MAP_INDEX,
+ INT32_ARRAY_EXTERNAL_MAP_INDEX,
+ UINT32_ARRAY_EXTERNAL_MAP_INDEX,
+ FLOAT32_ARRAY_EXTERNAL_MAP_INDEX,
+ FLOAT64_ARRAY_EXTERNAL_MAP_INDEX,
+ UINT8_CLAMPED_ARRAY_EXTERNAL_MAP_INDEX,
DATA_VIEW_FUN_INDEX,
MESSAGE_LISTENERS_INDEX,
MAKE_MESSAGE_FUN_INDEX,
@@ -328,7 +332,7 @@ class Context: public FixedArray {
ALLOW_CODE_GEN_FROM_STRINGS_INDEX,
ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX,
RUN_MICROTASKS_INDEX,
- ENQUEUE_EXTERNAL_MICROTASK_INDEX,
+ ENQUEUE_MICROTASK_INDEX,
IS_PROMISE_INDEX,
PROMISE_CREATE_INDEX,
PROMISE_RESOLVE_INDEX,
@@ -344,10 +348,15 @@ class Context: public FixedArray {
OBSERVERS_ENQUEUE_SPLICE_INDEX,
OBSERVERS_BEGIN_SPLICE_INDEX,
OBSERVERS_END_SPLICE_INDEX,
+ NATIVE_OBJECT_OBSERVE_INDEX,
+ NATIVE_OBJECT_GET_NOTIFIER_INDEX,
+ NATIVE_OBJECT_NOTIFIER_PERFORM_CHANGE,
SLOPPY_GENERATOR_FUNCTION_MAP_INDEX,
STRICT_GENERATOR_FUNCTION_MAP_INDEX,
GENERATOR_OBJECT_PROTOTYPE_MAP_INDEX,
- GENERATOR_RESULT_MAP_INDEX,
+ ITERATOR_RESULT_MAP_INDEX,
+ MAP_ITERATOR_MAP_INDEX,
+ SET_ITERATOR_MAP_INDEX,
// Properties from here are treated as weak references by the full GC.
// Scavenge treats them as strong references.
diff --git a/deps/v8/src/conversions-inl.h b/deps/v8/src/conversions-inl.h
index e503eb5027..43363f3738 100644
--- a/deps/v8/src/conversions-inl.h
+++ b/deps/v8/src/conversions-inl.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_CONVERSIONS_INL_H_
#define V8_CONVERSIONS_INL_H_
@@ -75,7 +52,11 @@ inline unsigned int FastD2UI(double x) {
if (x < k2Pow52) {
x += k2Pow52;
uint32_t result;
+#ifndef V8_TARGET_BIG_ENDIAN
Address mantissa_ptr = reinterpret_cast<Address>(&x);
+#else
+ Address mantissa_ptr = reinterpret_cast<Address>(&x) + kIntSize;
+#endif
// Copy least significant 32 bits of mantissa.
OS::MemCopy(&result, mantissa_ptr, sizeof(result));
return negative ? ~result + 1 : result;
diff --git a/deps/v8/src/conversions.cc b/deps/v8/src/conversions.cc
index 9c52d41e5d..14dbc2b7f8 100644
--- a/deps/v8/src/conversions.cc
+++ b/deps/v8/src/conversions.cc
@@ -1,36 +1,18 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <stdarg.h>
#include <limits.h>
#include <cmath>
+#include "v8.h"
+
+#include "assert-scope.h"
+#include "conversions.h"
#include "conversions-inl.h"
#include "dtoa.h"
+#include "factory.h"
#include "list-inl.h"
#include "strtod.h"
#include "utils.h"
@@ -44,6 +26,47 @@ namespace v8 {
namespace internal {
+namespace {
+
+// C++-style iterator adaptor for StringCharacterStream
+// (unlike C++ iterators the end-marker has different type).
+class StringCharacterStreamIterator {
+ public:
+ class EndMarker {};
+
+ explicit StringCharacterStreamIterator(StringCharacterStream* stream);
+
+ uint16_t operator*() const;
+ void operator++();
+ bool operator==(EndMarker const&) const { return end_; }
+ bool operator!=(EndMarker const& m) const { return !end_; }
+
+ private:
+ StringCharacterStream* const stream_;
+ uint16_t current_;
+ bool end_;
+};
+
+
+StringCharacterStreamIterator::StringCharacterStreamIterator(
+ StringCharacterStream* stream) : stream_(stream) {
+ ++(*this);
+}
+
+uint16_t StringCharacterStreamIterator::operator*() const {
+ return current_;
+}
+
+
+void StringCharacterStreamIterator::operator++() {
+ end_ = !stream_->HasMore();
+ if (!end_) {
+ current_ = stream_->GetNext();
+ }
+}
+} // End anonymous namespace.
+
+
double StringToDouble(UnicodeCache* unicode_cache,
const char* str, int flags, double empty_string_val) {
// We cast to const uint8_t* here to avoid instantiating the
@@ -56,7 +79,7 @@ double StringToDouble(UnicodeCache* unicode_cache,
double StringToDouble(UnicodeCache* unicode_cache,
- Vector<const char> str,
+ Vector<const uint8_t> str,
int flags,
double empty_string_val) {
// We cast to const uint8_t* here to avoid instantiating the
@@ -78,6 +101,23 @@ double StringToDouble(UnicodeCache* unicode_cache,
}
+// Converts a string into an integer.
+double StringToInt(UnicodeCache* unicode_cache,
+ Vector<const uint8_t> vector,
+ int radix) {
+ return InternalStringToInt(
+ unicode_cache, vector.start(), vector.start() + vector.length(), radix);
+}
+
+
+double StringToInt(UnicodeCache* unicode_cache,
+ Vector<const uc16> vector,
+ int radix) {
+ return InternalStringToInt(
+ unicode_cache, vector.start(), vector.start() + vector.length(), radix);
+}
+
+
const char* DoubleToCString(double v, Vector<char> buffer) {
switch (fpclassify(v)) {
case FP_NAN: return "NaN";
@@ -256,7 +296,6 @@ static char* CreateExponentialRepresentation(char* decimal_rep,
}
-
char* DoubleToExponentialCString(double value, int f) {
const int kMaxDigitsAfterPoint = 20;
// f might be -1 to signal that f was undefined in JavaScript.
@@ -443,4 +482,22 @@ char* DoubleToRadixCString(double value, int radix) {
return builder.Finalize();
}
+
+double StringToDouble(UnicodeCache* unicode_cache,
+ String* string,
+ int flags,
+ double empty_string_val) {
+ DisallowHeapAllocation no_gc;
+ String::FlatContent flat = string->GetFlatContent();
+ // ECMA-262 section 15.1.2.3, empty string is NaN
+ if (flat.IsAscii()) {
+ return StringToDouble(
+ unicode_cache, flat.ToOneByteVector(), flags, empty_string_val);
+ } else {
+ return StringToDouble(
+ unicode_cache, flat.ToUC16Vector(), flags, empty_string_val);
+ }
+}
+
+
} } // namespace v8::internal
diff --git a/deps/v8/src/conversions.h b/deps/v8/src/conversions.h
index f850f581f0..d6c99aa9f5 100644
--- a/deps/v8/src/conversions.h
+++ b/deps/v8/src/conversions.h
@@ -1,33 +1,15 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_CONVERSIONS_H_
#define V8_CONVERSIONS_H_
+#include <limits>
+
+#include "checks.h"
+#include "handles.h"
+#include "objects.h"
#include "utils.h"
namespace v8 {
@@ -122,7 +104,7 @@ enum ConversionFlags {
// Converts a string into a double value according to ECMA-262 9.3.1
double StringToDouble(UnicodeCache* unicode_cache,
- Vector<const char> str,
+ Vector<const uint8_t> str,
int flags,
double empty_string_val = 0);
double StringToDouble(UnicodeCache* unicode_cache,
@@ -135,6 +117,16 @@ double StringToDouble(UnicodeCache* unicode_cache,
int flags,
double empty_string_val = 0);
+// Converts a string into an integer.
+double StringToInt(UnicodeCache* unicode_cache,
+ Vector<const uint8_t> vector,
+ int radix);
+
+
+double StringToInt(UnicodeCache* unicode_cache,
+ Vector<const uc16> vector,
+ int radix);
+
const int kDoubleToCStringMinBufferSize = 100;
// Converts a double to a string value according to ECMA-262 9.8.1.
@@ -153,6 +145,77 @@ char* DoubleToExponentialCString(double value, int f);
char* DoubleToPrecisionCString(double value, int f);
char* DoubleToRadixCString(double value, int radix);
+
+static inline bool IsMinusZero(double value) {
+ static const DoubleRepresentation minus_zero(-0.0);
+ return DoubleRepresentation(value) == minus_zero;
+}
+
+
+// Integer32 is an integer that can be represented as a signed 32-bit
+// integer. It has to be in the range [-2^31, 2^31 - 1].
+// We also have to check for negative 0 as it is not an Integer32.
+static inline bool IsInt32Double(double value) {
+ return !IsMinusZero(value) &&
+ value >= kMinInt &&
+ value <= kMaxInt &&
+ value == FastI2D(FastD2I(value));
+}
+
+
+// Convert from Number object to C integer.
+inline int32_t NumberToInt32(Object* number) {
+ if (number->IsSmi()) return Smi::cast(number)->value();
+ return DoubleToInt32(number->Number());
+}
+
+
+inline uint32_t NumberToUint32(Object* number) {
+ if (number->IsSmi()) return Smi::cast(number)->value();
+ return DoubleToUint32(number->Number());
+}
+
+
+double StringToDouble(UnicodeCache* unicode_cache,
+ String* string,
+ int flags,
+ double empty_string_val = 0.0);
+
+
+inline bool TryNumberToSize(Isolate* isolate,
+ Object* number, size_t* result) {
+ SealHandleScope shs(isolate);
+ if (number->IsSmi()) {
+ int value = Smi::cast(number)->value();
+ ASSERT(static_cast<unsigned>(Smi::kMaxValue)
+ <= std::numeric_limits<size_t>::max());
+ if (value >= 0) {
+ *result = static_cast<size_t>(value);
+ return true;
+ }
+ return false;
+ } else {
+ ASSERT(number->IsHeapNumber());
+ double value = HeapNumber::cast(number)->value();
+ if (value >= 0 &&
+ value <= std::numeric_limits<size_t>::max()) {
+ *result = static_cast<size_t>(value);
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
+
+// Converts a number into size_t.
+inline size_t NumberToSize(Isolate* isolate,
+ Object* number) {
+ size_t result = 0;
+ bool is_valid = TryNumberToSize(isolate, number, &result);
+ CHECK(is_valid);
+ return result;
+}
+
} } // namespace v8::internal
#endif // V8_CONVERSIONS_H_
diff --git a/deps/v8/src/counters.cc b/deps/v8/src/counters.cc
index e7fab1c3dd..eb1b4c27f0 100644
--- a/deps/v8/src/counters.cc
+++ b/deps/v8/src/counters.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -76,4 +53,74 @@ void HistogramTimer::Stop() {
isolate()->event_logger()(name(), Logger::END);
}
+
+Counters::Counters(Isolate* isolate) {
+#define HT(name, caption) \
+ name##_ = HistogramTimer(#caption, 0, 10000, 50, isolate);
+ HISTOGRAM_TIMER_LIST(HT)
+#undef HT
+
+#define HP(name, caption) \
+ name##_ = Histogram(#caption, 0, 101, 100, isolate);
+ HISTOGRAM_PERCENTAGE_LIST(HP)
+#undef HP
+
+#define HM(name, caption) \
+ name##_ = Histogram(#caption, 1000, 500000, 50, isolate);
+ HISTOGRAM_MEMORY_LIST(HM)
+#undef HM
+
+#define SC(name, caption) \
+ name##_ = StatsCounter(isolate, "c:" #caption);
+
+ STATS_COUNTER_LIST_1(SC)
+ STATS_COUNTER_LIST_2(SC)
+#undef SC
+
+#define SC(name) \
+ count_of_##name##_ = StatsCounter(isolate, "c:" "V8.CountOf_" #name); \
+ size_of_##name##_ = StatsCounter(isolate, "c:" "V8.SizeOf_" #name);
+ INSTANCE_TYPE_LIST(SC)
+#undef SC
+
+#define SC(name) \
+ count_of_CODE_TYPE_##name##_ = \
+ StatsCounter(isolate, "c:" "V8.CountOf_CODE_TYPE-" #name); \
+ size_of_CODE_TYPE_##name##_ = \
+ StatsCounter(isolate, "c:" "V8.SizeOf_CODE_TYPE-" #name);
+ CODE_KIND_LIST(SC)
+#undef SC
+
+#define SC(name) \
+ count_of_FIXED_ARRAY_##name##_ = \
+ StatsCounter(isolate, "c:" "V8.CountOf_FIXED_ARRAY-" #name); \
+ size_of_FIXED_ARRAY_##name##_ = \
+ StatsCounter(isolate, "c:" "V8.SizeOf_FIXED_ARRAY-" #name);
+ FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC)
+#undef SC
+
+#define SC(name) \
+ count_of_CODE_AGE_##name##_ = \
+ StatsCounter(isolate, "c:" "V8.CountOf_CODE_AGE-" #name); \
+ size_of_CODE_AGE_##name##_ = \
+ StatsCounter(isolate, "c:" "V8.SizeOf_CODE_AGE-" #name);
+ CODE_AGE_LIST_COMPLETE(SC)
+#undef SC
+}
+
+
+void Counters::ResetHistograms() {
+#define HT(name, caption) name##_.Reset();
+ HISTOGRAM_TIMER_LIST(HT)
+#undef HT
+
+#define HP(name, caption) name##_.Reset();
+ HISTOGRAM_PERCENTAGE_LIST(HP)
+#undef HP
+
+#define HM(name, caption) name##_.Reset();
+ HISTOGRAM_MEMORY_LIST(HM)
+#undef HM
+}
+
} } // namespace v8::internal
diff --git a/deps/v8/src/counters.h b/deps/v8/src/counters.h
index 821c25f8ce..18a9aef29b 100644
--- a/deps/v8/src/counters.h
+++ b/deps/v8/src/counters.h
@@ -1,35 +1,15 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_COUNTERS_H_
#define V8_COUNTERS_H_
#include "../include/v8.h"
#include "allocation.h"
+#include "objects.h"
+#include "platform/elapsed-timer.h"
+#include "v8globals.h"
namespace v8 {
namespace internal {
@@ -307,6 +287,400 @@ class HistogramTimerScope BASE_EMBEDDED {
};
+#define HISTOGRAM_TIMER_LIST(HT) \
+ /* Garbage collection timers. */ \
+ HT(gc_compactor, V8.GCCompactor) \
+ HT(gc_scavenger, V8.GCScavenger) \
+ HT(gc_context, V8.GCContext) /* GC context cleanup time */ \
+ /* Parsing timers. */ \
+ HT(parse, V8.Parse) \
+ HT(parse_lazy, V8.ParseLazy) \
+ HT(pre_parse, V8.PreParse) \
+ /* Total compilation times. */ \
+ HT(compile, V8.Compile) \
+ HT(compile_eval, V8.CompileEval) \
+ HT(compile_lazy, V8.CompileLazy)
+
+#define HISTOGRAM_PERCENTAGE_LIST(HP) \
+ /* Heap fragmentation. */ \
+ HP(external_fragmentation_total, \
+ V8.MemoryExternalFragmentationTotal) \
+ HP(external_fragmentation_old_pointer_space, \
+ V8.MemoryExternalFragmentationOldPointerSpace) \
+ HP(external_fragmentation_old_data_space, \
+ V8.MemoryExternalFragmentationOldDataSpace) \
+ HP(external_fragmentation_code_space, \
+ V8.MemoryExternalFragmentationCodeSpace) \
+ HP(external_fragmentation_map_space, \
+ V8.MemoryExternalFragmentationMapSpace) \
+ HP(external_fragmentation_cell_space, \
+ V8.MemoryExternalFragmentationCellSpace) \
+ HP(external_fragmentation_property_cell_space, \
+ V8.MemoryExternalFragmentationPropertyCellSpace) \
+ HP(external_fragmentation_lo_space, \
+ V8.MemoryExternalFragmentationLoSpace) \
+ /* Percentages of heap committed to each space. */ \
+ HP(heap_fraction_new_space, \
+ V8.MemoryHeapFractionNewSpace) \
+ HP(heap_fraction_old_pointer_space, \
+ V8.MemoryHeapFractionOldPointerSpace) \
+ HP(heap_fraction_old_data_space, \
+ V8.MemoryHeapFractionOldDataSpace) \
+ HP(heap_fraction_code_space, \
+ V8.MemoryHeapFractionCodeSpace) \
+ HP(heap_fraction_map_space, \
+ V8.MemoryHeapFractionMapSpace) \
+ HP(heap_fraction_cell_space, \
+ V8.MemoryHeapFractionCellSpace) \
+ HP(heap_fraction_property_cell_space, \
+ V8.MemoryHeapFractionPropertyCellSpace) \
+ HP(heap_fraction_lo_space, \
+ V8.MemoryHeapFractionLoSpace) \
+ /* Percentage of crankshafted codegen. */ \
+ HP(codegen_fraction_crankshaft, \
+ V8.CodegenFractionCrankshaft) \
+
+
+#define HISTOGRAM_MEMORY_LIST(HM) \
+ HM(heap_sample_total_committed, V8.MemoryHeapSampleTotalCommitted) \
+ HM(heap_sample_total_used, V8.MemoryHeapSampleTotalUsed) \
+ HM(heap_sample_map_space_committed, \
+ V8.MemoryHeapSampleMapSpaceCommitted) \
+ HM(heap_sample_cell_space_committed, \
+ V8.MemoryHeapSampleCellSpaceCommitted) \
+ HM(heap_sample_property_cell_space_committed, \
+ V8.MemoryHeapSamplePropertyCellSpaceCommitted) \
+ HM(heap_sample_code_space_committed, \
+ V8.MemoryHeapSampleCodeSpaceCommitted) \
+ HM(heap_sample_maximum_committed, \
+ V8.MemoryHeapSampleMaximumCommitted) \
+
+
+// WARNING: STATS_COUNTER_LIST_* is a very large macro that is causing MSVC
+// Intellisense to crash. It was broken into two macros (each of length 40
+// lines) rather than one macro (of length about 80 lines) to work around
+// this problem. Please avoid using recursive macros of this length when
+// possible.
+#define STATS_COUNTER_LIST_1(SC) \
+ /* Global Handle Count*/ \
+ SC(global_handles, V8.GlobalHandles) \
+ /* OS Memory allocated */ \
+ SC(memory_allocated, V8.OsMemoryAllocated) \
+ SC(normalized_maps, V8.NormalizedMaps) \
+ SC(props_to_dictionary, V8.ObjectPropertiesToDictionary) \
+ SC(elements_to_dictionary, V8.ObjectElementsToDictionary) \
+ SC(alive_after_last_gc, V8.AliveAfterLastGC) \
+ SC(objs_since_last_young, V8.ObjsSinceLastYoung) \
+ SC(objs_since_last_full, V8.ObjsSinceLastFull) \
+ SC(string_table_capacity, V8.StringTableCapacity) \
+ SC(number_of_symbols, V8.NumberOfSymbols) \
+ SC(script_wrappers, V8.ScriptWrappers) \
+ SC(call_initialize_stubs, V8.CallInitializeStubs) \
+ SC(call_premonomorphic_stubs, V8.CallPreMonomorphicStubs) \
+ SC(call_normal_stubs, V8.CallNormalStubs) \
+ SC(call_megamorphic_stubs, V8.CallMegamorphicStubs) \
+ SC(arguments_adaptors, V8.ArgumentsAdaptors) \
+ SC(compilation_cache_hits, V8.CompilationCacheHits) \
+ SC(compilation_cache_misses, V8.CompilationCacheMisses) \
+ SC(string_ctor_calls, V8.StringConstructorCalls) \
+ SC(string_ctor_conversions, V8.StringConstructorConversions) \
+ SC(string_ctor_cached_number, V8.StringConstructorCachedNumber) \
+ SC(string_ctor_string_value, V8.StringConstructorStringValue) \
+ SC(string_ctor_gc_required, V8.StringConstructorGCRequired) \
+ /* Amount of evaled source code. */ \
+ SC(total_eval_size, V8.TotalEvalSize) \
+ /* Amount of loaded source code. */ \
+ SC(total_load_size, V8.TotalLoadSize) \
+ /* Amount of parsed source code. */ \
+ SC(total_parse_size, V8.TotalParseSize) \
+ /* Amount of source code skipped over using preparsing. */ \
+ SC(total_preparse_skipped, V8.TotalPreparseSkipped) \
+ /* Number of symbol lookups skipped using preparsing */ \
+ SC(total_preparse_symbols_skipped, V8.TotalPreparseSymbolSkipped) \
+ /* Amount of compiled source code. */ \
+ SC(total_compile_size, V8.TotalCompileSize) \
+ /* Amount of source code compiled with the full codegen. */ \
+ SC(total_full_codegen_source_size, V8.TotalFullCodegenSourceSize) \
+ /* Number of contexts created from scratch. */ \
+ SC(contexts_created_from_scratch, V8.ContextsCreatedFromScratch) \
+ /* Number of contexts created by partial snapshot. */ \
+ SC(contexts_created_by_snapshot, V8.ContextsCreatedBySnapshot) \
+ /* Number of code objects found from pc. */ \
+ SC(pc_to_code, V8.PcToCode) \
+ SC(pc_to_code_cached, V8.PcToCodeCached) \
+ /* The store-buffer implementation of the write barrier. */ \
+ SC(store_buffer_compactions, V8.StoreBufferCompactions) \
+ SC(store_buffer_overflows, V8.StoreBufferOverflows)
+
+
+#define STATS_COUNTER_LIST_2(SC) \
+ /* Number of code stubs. */ \
+ SC(code_stubs, V8.CodeStubs) \
+ /* Amount of stub code. */ \
+ SC(total_stubs_code_size, V8.TotalStubsCodeSize) \
+ /* Amount of (JS) compiled code. */ \
+ SC(total_compiled_code_size, V8.TotalCompiledCodeSize) \
+ SC(gc_compactor_caused_by_request, V8.GCCompactorCausedByRequest) \
+ SC(gc_compactor_caused_by_promoted_data, \
+ V8.GCCompactorCausedByPromotedData) \
+ SC(gc_compactor_caused_by_oldspace_exhaustion, \
+ V8.GCCompactorCausedByOldspaceExhaustion) \
+ SC(gc_last_resort_from_js, V8.GCLastResortFromJS) \
+ SC(gc_last_resort_from_handles, V8.GCLastResortFromHandles) \
+ /* How is the generic keyed-load stub used? */ \
+ SC(keyed_load_generic_smi, V8.KeyedLoadGenericSmi) \
+ SC(keyed_load_generic_symbol, V8.KeyedLoadGenericSymbol) \
+ SC(keyed_load_generic_lookup_cache, V8.KeyedLoadGenericLookupCache) \
+ SC(keyed_load_generic_slow, V8.KeyedLoadGenericSlow) \
+ SC(keyed_load_polymorphic_stubs, V8.KeyedLoadPolymorphicStubs) \
+ SC(keyed_load_external_array_slow, V8.KeyedLoadExternalArraySlow) \
+ /* How is the generic keyed-call stub used? */ \
+ SC(keyed_call_generic_smi_fast, V8.KeyedCallGenericSmiFast) \
+ SC(keyed_call_generic_smi_dict, V8.KeyedCallGenericSmiDict) \
+ SC(keyed_call_generic_lookup_cache, V8.KeyedCallGenericLookupCache) \
+ SC(keyed_call_generic_lookup_dict, V8.KeyedCallGenericLookupDict) \
+ SC(keyed_call_generic_slow, V8.KeyedCallGenericSlow) \
+ SC(keyed_call_generic_slow_load, V8.KeyedCallGenericSlowLoad) \
+ SC(named_load_global_stub, V8.NamedLoadGlobalStub) \
+ SC(named_store_global_inline, V8.NamedStoreGlobalInline) \
+ SC(named_store_global_inline_miss, V8.NamedStoreGlobalInlineMiss) \
+ SC(keyed_store_polymorphic_stubs, V8.KeyedStorePolymorphicStubs) \
+ SC(keyed_store_external_array_slow, V8.KeyedStoreExternalArraySlow) \
+ SC(store_normal_miss, V8.StoreNormalMiss) \
+ SC(store_normal_hit, V8.StoreNormalHit) \
+ SC(cow_arrays_created_stub, V8.COWArraysCreatedStub) \
+ SC(cow_arrays_created_runtime, V8.COWArraysCreatedRuntime) \
+ SC(cow_arrays_converted, V8.COWArraysConverted) \
+ SC(call_miss, V8.CallMiss) \
+ SC(keyed_call_miss, V8.KeyedCallMiss) \
+ SC(load_miss, V8.LoadMiss) \
+ SC(keyed_load_miss, V8.KeyedLoadMiss) \
+ SC(call_const, V8.CallConst) \
+ SC(call_const_fast_api, V8.CallConstFastApi) \
+ SC(call_const_interceptor, V8.CallConstInterceptor) \
+ SC(call_const_interceptor_fast_api, V8.CallConstInterceptorFastApi) \
+ SC(call_global_inline, V8.CallGlobalInline) \
+ SC(call_global_inline_miss, V8.CallGlobalInlineMiss) \
+ SC(constructed_objects, V8.ConstructedObjects) \
+ SC(constructed_objects_runtime, V8.ConstructedObjectsRuntime) \
+ SC(negative_lookups, V8.NegativeLookups) \
+ SC(negative_lookups_miss, V8.NegativeLookupsMiss) \
+ SC(megamorphic_stub_cache_probes, V8.MegamorphicStubCacheProbes) \
+ SC(megamorphic_stub_cache_misses, V8.MegamorphicStubCacheMisses) \
+ SC(megamorphic_stub_cache_updates, V8.MegamorphicStubCacheUpdates) \
+ SC(array_function_runtime, V8.ArrayFunctionRuntime) \
+ SC(array_function_native, V8.ArrayFunctionNative) \
+ SC(for_in, V8.ForIn) \
+ SC(enum_cache_hits, V8.EnumCacheHits) \
+ SC(enum_cache_misses, V8.EnumCacheMisses) \
+ SC(zone_segment_bytes, V8.ZoneSegmentBytes) \
+ SC(fast_new_closure_total, V8.FastNewClosureTotal) \
+ SC(fast_new_closure_try_optimized, V8.FastNewClosureTryOptimized) \
+ SC(fast_new_closure_install_optimized, V8.FastNewClosureInstallOptimized) \
+ SC(string_add_runtime, V8.StringAddRuntime) \
+ SC(string_add_native, V8.StringAddNative) \
+ SC(string_add_runtime_ext_to_ascii, V8.StringAddRuntimeExtToAscii) \
+ SC(sub_string_runtime, V8.SubStringRuntime) \
+ SC(sub_string_native, V8.SubStringNative) \
+ SC(string_add_make_two_char, V8.StringAddMakeTwoChar) \
+ SC(string_compare_native, V8.StringCompareNative) \
+ SC(string_compare_runtime, V8.StringCompareRuntime) \
+ SC(regexp_entry_runtime, V8.RegExpEntryRuntime) \
+ SC(regexp_entry_native, V8.RegExpEntryNative) \
+ SC(number_to_string_native, V8.NumberToStringNative) \
+ SC(number_to_string_runtime, V8.NumberToStringRuntime) \
+ SC(math_acos, V8.MathAcos) \
+ SC(math_asin, V8.MathAsin) \
+ SC(math_atan, V8.MathAtan) \
+ SC(math_atan2, V8.MathAtan2) \
+ SC(math_exp, V8.MathExp) \
+ SC(math_floor, V8.MathFloor) \
+ SC(math_log, V8.MathLog) \
+ SC(math_pow, V8.MathPow) \
+ SC(math_round, V8.MathRound) \
+ SC(math_sqrt, V8.MathSqrt) \
+ SC(stack_interrupts, V8.StackInterrupts) \
+ SC(runtime_profiler_ticks, V8.RuntimeProfilerTicks) \
+ SC(bounds_checks_eliminated, V8.BoundsChecksEliminated) \
+ SC(bounds_checks_hoisted, V8.BoundsChecksHoisted) \
+ SC(soft_deopts_requested, V8.SoftDeoptsRequested) \
+ SC(soft_deopts_inserted, V8.SoftDeoptsInserted) \
+ SC(soft_deopts_executed, V8.SoftDeoptsExecuted) \
+ /* Number of write barriers in generated code. */ \
+ SC(write_barriers_dynamic, V8.WriteBarriersDynamic) \
+ SC(write_barriers_static, V8.WriteBarriersStatic) \
+ SC(new_space_bytes_available, V8.MemoryNewSpaceBytesAvailable) \
+ SC(new_space_bytes_committed, V8.MemoryNewSpaceBytesCommitted) \
+ SC(new_space_bytes_used, V8.MemoryNewSpaceBytesUsed) \
+ SC(old_pointer_space_bytes_available, \
+ V8.MemoryOldPointerSpaceBytesAvailable) \
+ SC(old_pointer_space_bytes_committed, \
+ V8.MemoryOldPointerSpaceBytesCommitted) \
+ SC(old_pointer_space_bytes_used, V8.MemoryOldPointerSpaceBytesUsed) \
+ SC(old_data_space_bytes_available, V8.MemoryOldDataSpaceBytesAvailable) \
+ SC(old_data_space_bytes_committed, V8.MemoryOldDataSpaceBytesCommitted) \
+ SC(old_data_space_bytes_used, V8.MemoryOldDataSpaceBytesUsed) \
+ SC(code_space_bytes_available, V8.MemoryCodeSpaceBytesAvailable) \
+ SC(code_space_bytes_committed, V8.MemoryCodeSpaceBytesCommitted) \
+ SC(code_space_bytes_used, V8.MemoryCodeSpaceBytesUsed) \
+ SC(map_space_bytes_available, V8.MemoryMapSpaceBytesAvailable) \
+ SC(map_space_bytes_committed, V8.MemoryMapSpaceBytesCommitted) \
+ SC(map_space_bytes_used, V8.MemoryMapSpaceBytesUsed) \
+ SC(cell_space_bytes_available, V8.MemoryCellSpaceBytesAvailable) \
+ SC(cell_space_bytes_committed, V8.MemoryCellSpaceBytesCommitted) \
+ SC(cell_space_bytes_used, V8.MemoryCellSpaceBytesUsed) \
+ SC(property_cell_space_bytes_available, \
+ V8.MemoryPropertyCellSpaceBytesAvailable) \
+ SC(property_cell_space_bytes_committed, \
+ V8.MemoryPropertyCellSpaceBytesCommitted) \
+ SC(property_cell_space_bytes_used, \
+ V8.MemoryPropertyCellSpaceBytesUsed) \
+ SC(lo_space_bytes_available, V8.MemoryLoSpaceBytesAvailable) \
+ SC(lo_space_bytes_committed, V8.MemoryLoSpaceBytesCommitted) \
+ SC(lo_space_bytes_used, V8.MemoryLoSpaceBytesUsed)
+
+
+// This file contains all the v8 counters that are in use.
+class Counters {
+ public:
+#define HT(name, caption) \
+ HistogramTimer* name() { return &name##_; }
+ HISTOGRAM_TIMER_LIST(HT)
+#undef HT
+
+#define HP(name, caption) \
+ Histogram* name() { return &name##_; }
+ HISTOGRAM_PERCENTAGE_LIST(HP)
+#undef HP
+
+#define HM(name, caption) \
+ Histogram* name() { return &name##_; }
+ HISTOGRAM_MEMORY_LIST(HM)
+#undef HM
+
+#define SC(name, caption) \
+ StatsCounter* name() { return &name##_; }
+ STATS_COUNTER_LIST_1(SC)
+ STATS_COUNTER_LIST_2(SC)
+#undef SC
+
+#define SC(name) \
+ StatsCounter* count_of_##name() { return &count_of_##name##_; } \
+ StatsCounter* size_of_##name() { return &size_of_##name##_; }
+ INSTANCE_TYPE_LIST(SC)
+#undef SC
+
+#define SC(name) \
+ StatsCounter* count_of_CODE_TYPE_##name() \
+ { return &count_of_CODE_TYPE_##name##_; } \
+ StatsCounter* size_of_CODE_TYPE_##name() \
+ { return &size_of_CODE_TYPE_##name##_; }
+ CODE_KIND_LIST(SC)
+#undef SC
+
+#define SC(name) \
+ StatsCounter* count_of_FIXED_ARRAY_##name() \
+ { return &count_of_FIXED_ARRAY_##name##_; } \
+ StatsCounter* size_of_FIXED_ARRAY_##name() \
+ { return &size_of_FIXED_ARRAY_##name##_; }
+ FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC)
+#undef SC
+
+#define SC(name) \
+ StatsCounter* count_of_CODE_AGE_##name() \
+ { return &count_of_CODE_AGE_##name##_; } \
+ StatsCounter* size_of_CODE_AGE_##name() \
+ { return &size_of_CODE_AGE_##name##_; }
+ CODE_AGE_LIST_COMPLETE(SC)
+#undef SC
+
+ enum Id {
+#define RATE_ID(name, caption) k_##name,
+ HISTOGRAM_TIMER_LIST(RATE_ID)
+#undef RATE_ID
+#define PERCENTAGE_ID(name, caption) k_##name,
+ HISTOGRAM_PERCENTAGE_LIST(PERCENTAGE_ID)
+#undef PERCENTAGE_ID
+#define MEMORY_ID(name, caption) k_##name,
+ HISTOGRAM_MEMORY_LIST(MEMORY_ID)
+#undef MEMORY_ID
+#define COUNTER_ID(name, caption) k_##name,
+ STATS_COUNTER_LIST_1(COUNTER_ID)
+ STATS_COUNTER_LIST_2(COUNTER_ID)
+#undef COUNTER_ID
+#define COUNTER_ID(name) kCountOf##name, kSizeOf##name,
+ INSTANCE_TYPE_LIST(COUNTER_ID)
+#undef COUNTER_ID
+#define COUNTER_ID(name) kCountOfCODE_TYPE_##name, \
+ kSizeOfCODE_TYPE_##name,
+ CODE_KIND_LIST(COUNTER_ID)
+#undef COUNTER_ID
+#define COUNTER_ID(name) kCountOfFIXED_ARRAY__##name, \
+ kSizeOfFIXED_ARRAY__##name,
+ FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(COUNTER_ID)
+#undef COUNTER_ID
+#define COUNTER_ID(name) kCountOfCODE_AGE__##name, \
+ kSizeOfCODE_AGE__##name,
+ CODE_AGE_LIST_COMPLETE(COUNTER_ID)
+#undef COUNTER_ID
+ stats_counter_count
+ };
+
+ void ResetHistograms();
+
+ private:
+#define HT(name, caption) \
+ HistogramTimer name##_;
+ HISTOGRAM_TIMER_LIST(HT)
+#undef HT
+
+#define HP(name, caption) \
+ Histogram name##_;
+ HISTOGRAM_PERCENTAGE_LIST(HP)
+#undef HP
+
+#define HM(name, caption) \
+ Histogram name##_;
+ HISTOGRAM_MEMORY_LIST(HM)
+#undef HM
+
+#define SC(name, caption) \
+ StatsCounter name##_;
+ STATS_COUNTER_LIST_1(SC)
+ STATS_COUNTER_LIST_2(SC)
+#undef SC
+
+#define SC(name) \
+ StatsCounter size_of_##name##_; \
+ StatsCounter count_of_##name##_;
+ INSTANCE_TYPE_LIST(SC)
+#undef SC
+
+#define SC(name) \
+ StatsCounter size_of_CODE_TYPE_##name##_; \
+ StatsCounter count_of_CODE_TYPE_##name##_;
+ CODE_KIND_LIST(SC)
+#undef SC
+
+#define SC(name) \
+ StatsCounter size_of_FIXED_ARRAY_##name##_; \
+ StatsCounter count_of_FIXED_ARRAY_##name##_;
+ FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC)
+#undef SC
+
+#define SC(name) \
+ StatsCounter size_of_CODE_AGE_##name##_; \
+ StatsCounter count_of_CODE_AGE_##name##_;
+ CODE_AGE_LIST_COMPLETE(SC)
+#undef SC
+
+ friend class Isolate;
+
+ explicit Counters(Isolate* isolate);
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Counters);
+};
+
} } // namespace v8::internal
#endif // V8_COUNTERS_H_
diff --git a/deps/v8/src/cpu-profiler-inl.h b/deps/v8/src/cpu-profiler-inl.h
index 7bfbf5c57c..c4efef1b32 100644
--- a/deps/v8/src/cpu-profiler-inl.h
+++ b/deps/v8/src/cpu-profiler-inl.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_CPU_PROFILER_INL_H_
#define V8_CPU_PROFILER_INL_H_
diff --git a/deps/v8/src/cpu-profiler.cc b/deps/v8/src/cpu-profiler.cc
index 41f3e98644..abe29340d0 100644
--- a/deps/v8/src/cpu-profiler.cc
+++ b/deps/v8/src/cpu-profiler.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -432,7 +409,6 @@ void CpuProfiler::StartProfiling(const char* title, bool record_samples) {
if (profiles_->StartProfiling(title, record_samples)) {
StartProcessorIfNotStarted();
}
- processor_->AddCurrentStack(isolate_);
}
@@ -442,29 +418,32 @@ void CpuProfiler::StartProfiling(String* title, bool record_samples) {
void CpuProfiler::StartProcessorIfNotStarted() {
- if (processor_ == NULL) {
- Logger* logger = isolate_->logger();
- // Disable logging when using the new implementation.
- saved_is_logging_ = logger->is_logging_;
- logger->is_logging_ = false;
- generator_ = new ProfileGenerator(profiles_);
- Sampler* sampler = logger->sampler();
- processor_ = new ProfilerEventsProcessor(
- generator_, sampler, sampling_interval_);
- is_profiling_ = true;
- // Enumerate stuff we already have in the heap.
- ASSERT(isolate_->heap()->HasBeenSetUp());
- if (!FLAG_prof_browser_mode) {
- logger->LogCodeObjects();
- }
- logger->LogCompiledFunctions();
- logger->LogAccessorCallbacks();
- LogBuiltins();
- // Enable stack sampling.
- sampler->SetHasProcessingThread(true);
- sampler->IncreaseProfilingDepth();
- processor_->StartSynchronously();
+ if (processor_ != NULL) {
+ processor_->AddCurrentStack(isolate_);
+ return;
}
+ Logger* logger = isolate_->logger();
+ // Disable logging when using the new implementation.
+ saved_is_logging_ = logger->is_logging_;
+ logger->is_logging_ = false;
+ generator_ = new ProfileGenerator(profiles_);
+ Sampler* sampler = logger->sampler();
+ processor_ = new ProfilerEventsProcessor(
+ generator_, sampler, sampling_interval_);
+ is_profiling_ = true;
+ // Enumerate stuff we already have in the heap.
+ ASSERT(isolate_->heap()->HasBeenSetUp());
+ if (!FLAG_prof_browser_mode) {
+ logger->LogCodeObjects();
+ }
+ logger->LogCompiledFunctions();
+ logger->LogAccessorCallbacks();
+ LogBuiltins();
+ // Enable stack sampling.
+ sampler->SetHasProcessingThread(true);
+ sampler->IncreaseProfilingDepth();
+ processor_->AddCurrentStack(isolate_);
+ processor_->StartSynchronously();
}
diff --git a/deps/v8/src/cpu-profiler.h b/deps/v8/src/cpu-profiler.h
index a9f034f0c7..e87fe9e772 100644
--- a/deps/v8/src/cpu-profiler.h
+++ b/deps/v8/src/cpu-profiler.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_CPU_PROFILER_H_
#define V8_CPU_PROFILER_H_
diff --git a/deps/v8/src/cpu.cc b/deps/v8/src/cpu.cc
index 1e622495f4..c600eda10b 100644
--- a/deps/v8/src/cpu.cc
+++ b/deps/v8/src/cpu.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "cpu.h"
diff --git a/deps/v8/src/cpu.h b/deps/v8/src/cpu.h
index b2e9f7da7e..0315435b20 100644
--- a/deps/v8/src/cpu.h
+++ b/deps/v8/src/cpu.h
@@ -1,29 +1,6 @@
// Copyright 2006-2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This module contains the architecture-specific code. This make the rest of
// the code less dependent on differences between different processor
@@ -102,11 +79,6 @@ class CPU V8_FINAL BASE_EMBEDDED {
// Returns the number of processors online.
static int NumberOfProcessorsOnline();
- // Initializes the cpu architecture support. Called once at VM startup.
- static void SetUp();
-
- static bool SupportsCrankshaft();
-
// Flush instruction cache.
static void FlushICache(void* start, size_t size);
diff --git a/deps/v8/src/d8-debug.cc b/deps/v8/src/d8-debug.cc
index 7eb2016bd3..7c1beaf2e5 100644
--- a/deps/v8/src/d8-debug.cc
+++ b/deps/v8/src/d8-debug.cc
@@ -1,31 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifdef ENABLE_DEBUGGER_SUPPORT
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "d8.h"
#include "d8-debug.h"
@@ -370,5 +345,3 @@ void KeyboardThread::Run() {
} // namespace v8
-
-#endif // ENABLE_DEBUGGER_SUPPORT
diff --git a/deps/v8/src/d8-debug.h b/deps/v8/src/d8-debug.h
index 2d4f5e1503..c211be7590 100644
--- a/deps/v8/src/d8-debug.h
+++ b/deps/v8/src/d8-debug.h
@@ -1,29 +1,6 @@
// Copyright 2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_D8_DEBUG_H_
#define V8_D8_DEBUG_H_
diff --git a/deps/v8/src/d8-posix.cc b/deps/v8/src/d8-posix.cc
index 36ade48b8a..869cd53133 100644
--- a/deps/v8/src/d8-posix.cc
+++ b/deps/v8/src/d8-posix.cc
@@ -1,29 +1,6 @@
// Copyright 2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <stdlib.h>
diff --git a/deps/v8/src/d8-readline.cc b/deps/v8/src/d8-readline.cc
index 57b63bf4e1..cb59f6ef13 100644
--- a/deps/v8/src/d8-readline.cc
+++ b/deps/v8/src/d8-readline.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <stdio.h> // NOLINT
#include <string.h> // NOLINT
diff --git a/deps/v8/src/d8-windows.cc b/deps/v8/src/d8-windows.cc
index edf5085d49..8e0dc96b6d 100644
--- a/deps/v8/src/d8-windows.cc
+++ b/deps/v8/src/d8-windows.cc
@@ -1,29 +1,6 @@
// Copyright 2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "d8.h"
diff --git a/deps/v8/src/d8.cc b/deps/v8/src/d8.cc
index 7ac0c6546a..396d68b7fa 100644
--- a/deps/v8/src/d8.cc
+++ b/deps/v8/src/d8.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Defined when linking against shared lib on Windows.
@@ -67,7 +44,7 @@
#include "natives.h"
#include "platform.h"
#include "v8.h"
-#endif // V8_SHARED
+#endif // !V8_SHARED
#if !defined(_WIN32) && !defined(_WIN64)
#include <unistd.h> // NOLINT
@@ -163,7 +140,7 @@ CounterCollection* Shell::counters_ = &local_counters_;
i::Mutex Shell::context_mutex_;
const i::TimeTicks Shell::kInitialTicks = i::TimeTicks::HighResolutionNow();
Persistent<Context> Shell::utility_context_;
-#endif // V8_SHARED
+#endif // !V8_SHARED
Persistent<Context> Shell::evaluation_context_;
ShellOptions Shell::options;
@@ -178,7 +155,7 @@ bool CounterMap::Match(void* key1, void* key2) {
const char* name2 = reinterpret_cast<const char*>(key2);
return strcmp(name1, name2) == 0;
}
-#endif // V8_SHARED
+#endif // !V8_SHARED
// Converts a V8 value to a C string.
@@ -193,11 +170,11 @@ bool Shell::ExecuteString(Isolate* isolate,
Handle<Value> name,
bool print_result,
bool report_exceptions) {
-#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
+#ifndef V8_SHARED
bool FLAG_debugger = i::FLAG_debugger;
#else
bool FLAG_debugger = false;
-#endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
+#endif // !V8_SHARED
HandleScope handle_scope(isolate);
TryCatch try_catch;
options.script_executed = true;
@@ -317,7 +294,7 @@ void Shell::PerformanceNow(const v8::FunctionCallbackInfo<v8::Value>& args) {
i::TimeDelta delta = i::TimeTicks::HighResolutionNow() - kInitialTicks;
args.GetReturnValue().Set(delta.InMillisecondsF());
}
-#endif // V8_SHARED
+#endif // !V8_SHARED
// Realm.current() returns the index of the currently active realm.
@@ -561,14 +538,14 @@ void Shell::Version(const v8::FunctionCallbackInfo<v8::Value>& args) {
void Shell::ReportException(Isolate* isolate, v8::TryCatch* try_catch) {
HandleScope handle_scope(isolate);
-#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
+#ifndef V8_SHARED
Handle<Context> utility_context;
bool enter_context = !isolate->InContext();
if (enter_context) {
utility_context = Local<Context>::New(isolate, utility_context_);
utility_context->Enter();
}
-#endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
+#endif // !V8_SHARED
v8::String::Utf8Value exception(try_catch->Exception());
const char* exception_string = ToCString(exception);
Handle<Message> message = try_catch->Message();
@@ -603,9 +580,9 @@ void Shell::ReportException(Isolate* isolate, v8::TryCatch* try_catch) {
}
}
printf("\n");
-#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
+#ifndef V8_SHARED
if (enter_context) utility_context->Exit();
-#endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
+#endif // !V8_SHARED
}
@@ -629,7 +606,6 @@ Handle<Array> Shell::GetCompletions(Isolate* isolate,
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
Local<Object> Shell::DebugMessageDetails(Isolate* isolate,
Handle<String> message) {
EscapableHandleScope handle_scope(isolate);
@@ -670,11 +646,8 @@ void Shell::DispatchDebugMessages() {
v8::Context::Scope context_scope(context);
v8::Debug::ProcessDebugMessages();
}
-#endif // ENABLE_DEBUGGER_SUPPORT
-#endif // V8_SHARED
-#ifndef V8_SHARED
int32_t* Counter::Bind(const char* name, bool is_histogram) {
int i;
for (i = 0; i < kMaxNameSize - 1 && name[i]; i++)
@@ -786,7 +759,6 @@ void Shell::InstallUtilityScript(Isolate* isolate) {
evaluation_context->SetSecurityToken(Undefined(isolate));
v8::Context::Scope context_scope(utility_context);
-#ifdef ENABLE_DEBUGGER_SUPPORT
if (i::FLAG_debugger) printf("JavaScript debugger enabled\n");
// Install the debugger object in the utility scope
i::Debug* debug = reinterpret_cast<i::Isolate*>(isolate)->debug();
@@ -797,7 +769,6 @@ void Shell::InstallUtilityScript(Isolate* isolate) {
Utils::ToLocal(js_debug));
debug->debug_context()->set_security_token(
reinterpret_cast<i::Isolate*>(isolate)->heap()->undefined_value());
-#endif // ENABLE_DEBUGGER_SUPPORT
// Run the d8 shell utility script in the utility context
int source_index = i::NativesCollection<i::D8>::GetIndex("d8");
@@ -824,14 +795,12 @@ void Shell::InstallUtilityScript(Isolate* isolate) {
i::SharedFunctionInfo::cast(*compiled_script)->script()));
script_object->set_type(i::Smi::FromInt(i::Script::TYPE_NATIVE));
-#ifdef ENABLE_DEBUGGER_SUPPORT
// Start the in-process debugger if requested.
if (i::FLAG_debugger && !i::FLAG_debugger_agent) {
v8::Debug::SetDebugEventListener2(HandleDebugEvent);
}
-#endif // ENABLE_DEBUGGER_SUPPORT
}
-#endif // V8_SHARED
+#endif // !V8_SHARED
#ifdef COMPRESS_STARTUP_DATA_BZ2
@@ -907,13 +876,13 @@ Handle<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
FunctionTemplate::New(isolate, PerformanceNow));
global_template->Set(String::NewFromUtf8(isolate, "performance"),
performance_template);
-#endif // V8_SHARED
+#endif // !V8_SHARED
#if !defined(V8_SHARED) && !defined(_WIN32) && !defined(_WIN64)
Handle<ObjectTemplate> os_templ = ObjectTemplate::New(isolate);
AddOSMethods(isolate, os_templ);
global_template->Set(String::NewFromUtf8(isolate, "os"), os_templ);
-#endif // V8_SHARED
+#endif // !V8_SHARED && !_WIN32 && !_WIN64
return global_template;
}
@@ -939,7 +908,7 @@ void Shell::Initialize(Isolate* isolate) {
V8::SetCreateHistogramFunction(CreateHistogram);
V8::SetAddHistogramSampleFunction(AddHistogramSample);
}
-#endif // V8_SHARED
+#endif // !V8_SHARED
}
@@ -952,14 +921,12 @@ void Shell::InitializeDebugger(Isolate* isolate) {
utility_context_.Reset(isolate,
Context::New(isolate, NULL, global_template));
-#ifdef ENABLE_DEBUGGER_SUPPORT
// Start the debugger agent if requested.
if (i::FLAG_debugger_agent) {
v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port, true);
v8::Debug::SetDebugMessageDispatchHandler(DispatchDebugMessages, true);
}
-#endif // ENABLE_DEBUGGER_SUPPORT
-#endif // V8_SHARED
+#endif // !V8_SHARED
}
@@ -967,7 +934,7 @@ Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
#ifndef V8_SHARED
// This needs to be a critical section since this is not thread-safe
i::LockGuard<i::Mutex> lock_guard(&context_mutex_);
-#endif // V8_SHARED
+#endif // !V8_SHARED
// Initialize the global objects
Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
EscapableHandleScope handle_scope(isolate);
@@ -982,14 +949,14 @@ Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
factory->NewFixedArray(js_args.argc);
for (int j = 0; j < js_args.argc; j++) {
i::Handle<i::String> arg =
- factory->NewStringFromUtf8(i::CStrVector(js_args[j]));
+ factory->NewStringFromUtf8(i::CStrVector(js_args[j])).ToHandleChecked();
arguments_array->set(j, *arg);
}
i::Handle<i::JSArray> arguments_jsarray =
factory->NewJSArrayWithElements(arguments_array);
context->Global()->Set(String::NewFromUtf8(isolate, "arguments"),
Utils::ToLocal(arguments_jsarray));
-#endif // V8_SHARED
+#endif // !V8_SHARED
return handle_scope.Escape(context);
}
@@ -1013,7 +980,7 @@ struct CounterAndKey {
inline bool operator<(const CounterAndKey& lhs, const CounterAndKey& rhs) {
return strcmp(lhs.key, rhs.key) < 0;
}
-#endif // V8_SHARED
+#endif // !V8_SHARED
void Shell::OnExit() {
@@ -1054,7 +1021,7 @@ void Shell::OnExit() {
}
delete counters_file_;
delete counter_map_;
-#endif // V8_SHARED
+#endif // !V8_SHARED
}
@@ -1169,7 +1136,7 @@ static char* ReadLine(char* data) {
static char* ReadWord(char* data) {
return ReadToken(data, ' ');
}
-#endif // V8_SHARED
+#endif // !V8_SHARED
// Reads a file into a v8 string.
@@ -1267,14 +1234,14 @@ void ShellThread::Run() {
ptr = next_line;
}
}
-#endif // V8_SHARED
+#endif // !V8_SHARED
SourceGroup::~SourceGroup() {
#ifndef V8_SHARED
delete thread_;
thread_ = NULL;
-#endif // V8_SHARED
+#endif // !V8_SHARED
}
@@ -1382,7 +1349,7 @@ void SourceGroup::WaitForThread() {
done_semaphore_.Wait();
}
}
-#endif // V8_SHARED
+#endif // !V8_SHARED
bool Shell::SetOptions(int argc, char* argv[]) {
@@ -1436,7 +1403,7 @@ bool Shell::SetOptions(int argc, char* argv[]) {
#else
options.dump_heap_constants = true;
argv[i] = NULL;
-#endif
+#endif // V8_SHARED
} else if (strcmp(argv[i], "--throws") == 0) {
options.expected_to_throw = true;
argv[i] = NULL;
@@ -1477,7 +1444,7 @@ bool Shell::SetOptions(int argc, char* argv[]) {
printf("-p requires a file containing a list of files as parameter\n");
return false;
}
-#endif // V8_SHARED
+#endif // !V8_SHARED
v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
@@ -1523,7 +1490,7 @@ int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) {
for (int i = 1; i < options.num_isolates; ++i) {
options.isolate_sources[i].StartExecuteInThread();
}
-#endif // V8_SHARED
+#endif // !V8_SHARED
{ // NOLINT
Locker lock(isolate);
{
@@ -1532,13 +1499,13 @@ int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) {
if (options.last_run) {
// Keep using the same context in the interactive shell.
evaluation_context_.Reset(isolate, context);
-#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
+#ifndef V8_SHARED
// If the interactive debugger is enabled make sure to activate
// it before running the files passed on the command line.
if (i::FLAG_debugger) {
InstallUtilityScript(isolate);
}
-#endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
+#endif // !V8_SHARED
}
{
Context::Scope cscope(context);
@@ -1565,7 +1532,7 @@ int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) {
thread->Join();
delete thread;
}
-#endif // V8_SHARED
+#endif // !V8_SHARED
return 0;
}
@@ -1639,7 +1606,7 @@ static void DumpHeapConstants(i::Isolate* isolate) {
printf("}\n");
#undef ROOT_LIST_CASE
}
-#endif // V8_SHARED
+#endif // !V8_SHARED
class ShellArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
@@ -1696,6 +1663,7 @@ int Shell::Main(int argc, char* argv[]) {
#ifndef V8_SHARED
v8::ResourceConstraints constraints;
constraints.ConfigureDefaults(i::OS::TotalPhysicalMemory(),
+ i::OS::MaxVirtualMemory(),
i::CPU::NumberOfProcessorsOnline());
v8::SetResourceConstraints(isolate, &constraints);
#endif
@@ -1742,25 +1710,25 @@ int Shell::Main(int argc, char* argv[]) {
}
-#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
+#ifndef V8_SHARED
// Run remote debugger if requested, but never on --test
if (i::FLAG_remote_debugger && !options.test_shell) {
InstallUtilityScript(isolate);
RunRemoteDebugger(isolate, i::FLAG_debugger_port);
return 0;
}
-#endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
+#endif // !V8_SHARED
// Run interactive shell if explicitly requested or if no script has been
// executed, but never on --test
if (( options.interactive_shell || !options.script_executed )
&& !options.test_shell ) {
-#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
+#ifndef V8_SHARED
if (!i::FLAG_debugger) {
InstallUtilityScript(isolate);
}
-#endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
+#endif // !V8_SHARED
RunShell(isolate);
}
}
diff --git a/deps/v8/src/d8.h b/deps/v8/src/d8.h
index 3edd8a7307..bf290238bb 100644
--- a/deps/v8/src/d8.h
+++ b/deps/v8/src/d8.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_D8_H_
#define V8_D8_H_
@@ -35,7 +12,7 @@
#include "v8.h"
#else
#include "../include/v8.h"
-#endif // V8_SHARED
+#endif // !V8_SHARED
namespace v8 {
@@ -113,7 +90,7 @@ class CounterMap {
static bool Match(void* key1, void* key2);
i::HashMap hash_map_;
};
-#endif // V8_SHARED
+#endif // !V8_SHARED
class LineEditor {
@@ -143,7 +120,7 @@ class SourceGroup {
next_semaphore_(0),
done_semaphore_(0),
thread_(NULL),
-#endif // V8_SHARED
+#endif // !V8_SHARED
argv_(NULL),
begin_offset_(0),
end_offset_(0) {}
@@ -183,7 +160,7 @@ class SourceGroup {
i::Semaphore next_semaphore_;
i::Semaphore done_semaphore_;
i::Thread* thread_;
-#endif // V8_SHARED
+#endif // !V8_SHARED
void ExitShell(int exit_code);
Handle<String> ReadFile(Isolate* isolate, const char* name);
@@ -221,7 +198,7 @@ class ShellOptions {
#ifndef V8_SHARED
num_parallel_files(0),
parallel_files(NULL),
-#endif // V8_SHARED
+#endif // !V8_SHARED
script_executed(false),
last_run(true),
send_idle_notification(false),
@@ -239,14 +216,14 @@ class ShellOptions {
~ShellOptions() {
#ifndef V8_SHARED
delete[] parallel_files;
-#endif // V8_SHARED
+#endif // !V8_SHARED
delete[] isolate_sources;
}
#ifndef V8_SHARED
int num_parallel_files;
char** parallel_files;
-#endif // V8_SHARED
+#endif // !V8_SHARED
bool script_executed;
bool last_run;
bool send_idle_notification;
@@ -295,16 +272,14 @@ class Shell : public i::AllStatic {
static void AddHistogramSample(void* histogram, int sample);
static void MapCounters(const char* name);
-#ifdef ENABLE_DEBUGGER_SUPPORT
static Local<Object> DebugMessageDetails(Isolate* isolate,
Handle<String> message);
static Local<Value> DebugCommandToJSONRequest(Isolate* isolate,
Handle<String> command);
static void DispatchDebugMessages();
-#endif // ENABLE_DEBUGGER_SUPPORT
static void PerformanceNow(const v8::FunctionCallbackInfo<v8::Value>& args);
-#endif // V8_SHARED
+#endif // !V8_SHARED
static void RealmCurrent(const v8::FunctionCallbackInfo<v8::Value>& args);
static void RealmOwner(const v8::FunctionCallbackInfo<v8::Value>& args);
@@ -400,7 +375,7 @@ class Shell : public i::AllStatic {
static Counter* GetCounter(const char* name, bool is_histogram);
static void InstallUtilityScript(Isolate* isolate);
-#endif // V8_SHARED
+#endif // !V8_SHARED
static void Initialize(Isolate* isolate);
static void InitializeDebugger(Isolate* isolate);
static void RunShell(Isolate* isolate);
diff --git a/deps/v8/src/d8.js b/deps/v8/src/d8.js
index 35b61d54ee..0c1f32dc8d 100644
--- a/deps/v8/src/d8.js
+++ b/deps/v8/src/d8.js
@@ -1,29 +1,6 @@
// Copyright 2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
"use strict";
diff --git a/deps/v8/src/data-flow.cc b/deps/v8/src/data-flow.cc
index 6a3b05cc86..a2df933682 100644
--- a/deps/v8/src/data-flow.cc
+++ b/deps/v8/src/data-flow.cc
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/data-flow.h b/deps/v8/src/data-flow.h
index 8ceccf67c5..98435e603c 100644
--- a/deps/v8/src/data-flow.h
+++ b/deps/v8/src/data-flow.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_DATAFLOW_H_
#define V8_DATAFLOW_H_
diff --git a/deps/v8/src/date.cc b/deps/v8/src/date.cc
index 70d6be989f..e0fb5ee125 100644
--- a/deps/v8/src/date.cc
+++ b/deps/v8/src/date.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "date.h"
@@ -49,9 +26,10 @@ static const char kDaysInMonths[] =
void DateCache::ResetDateCache() {
static const int kMaxStamp = Smi::kMaxValue;
- stamp_ = Smi::FromInt(stamp_->value() + 1);
- if (stamp_->value() > kMaxStamp) {
+ if (stamp_->value() >= kMaxStamp) {
stamp_ = Smi::FromInt(0);
+ } else {
+ stamp_ = Smi::FromInt(stamp_->value() + 1);
}
ASSERT(stamp_ != Smi::FromInt(kInvalidStamp));
for (int i = 0; i < kDSTSize; ++i) {
diff --git a/deps/v8/src/date.h b/deps/v8/src/date.h
index e9c9d9cb06..a2af685d27 100644
--- a/deps/v8/src/date.h
+++ b/deps/v8/src/date.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_DATE_H_
#define V8_DATE_H_
diff --git a/deps/v8/src/date.js b/deps/v8/src/date.js
index b7ecbeb397..2a445979e6 100644
--- a/deps/v8/src/date.js
+++ b/deps/v8/src/date.js
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file relies on the fact that the following declarations have been made
// in v8natives.js:
diff --git a/deps/v8/src/dateparser-inl.h b/deps/v8/src/dateparser-inl.h
index 3cb36fa433..4e866e18d2 100644
--- a/deps/v8/src/dateparser-inl.h
+++ b/deps/v8/src/dateparser-inl.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_DATEPARSER_INL_H_
#define V8_DATEPARSER_INL_H_
diff --git a/deps/v8/src/dateparser.cc b/deps/v8/src/dateparser.cc
index 3964e81178..0c2c18b34c 100644
--- a/deps/v8/src/dateparser.cc
+++ b/deps/v8/src/dateparser.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/dateparser.h b/deps/v8/src/dateparser.h
index 7dc489de34..1b4efb6ae1 100644
--- a/deps/v8/src/dateparser.h
+++ b/deps/v8/src/dateparser.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_DATEPARSER_H_
#define V8_DATEPARSER_H_
diff --git a/deps/v8/src/debug-agent.cc b/deps/v8/src/debug-agent.cc
index 49790cee99..94f334bfe4 100644
--- a/deps/v8/src/debug-agent.cc
+++ b/deps/v8/src/debug-agent.cc
@@ -1,31 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifdef ENABLE_DEBUGGER_SUPPORT
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
#include "debug.h"
@@ -229,10 +204,10 @@ void DebuggerAgentSession::Run() {
decoder.WriteUtf16(temp.start(), utf16_length);
// Send the request received to the debugger.
- v8::Debug::SendCommand(temp.start(),
+ v8::Debug::SendCommand(reinterpret_cast<v8::Isolate*>(agent_->isolate()),
+ temp.start(),
utf16_length,
- NULL,
- reinterpret_cast<v8::Isolate*>(agent_->isolate()));
+ NULL);
if (is_closing_session) {
// Session is closed.
@@ -504,5 +479,3 @@ int DebuggerAgentUtil::ReceiveAll(Socket* conn, char* data, int len) {
}
} } // namespace v8::internal
-
-#endif // ENABLE_DEBUGGER_SUPPORT
diff --git a/deps/v8/src/debug-agent.h b/deps/v8/src/debug-agent.h
index e81e4cd6aa..3e3f25a5dd 100644
--- a/deps/v8/src/debug-agent.h
+++ b/deps/v8/src/debug-agent.h
@@ -1,34 +1,10 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_DEBUG_AGENT_H_
#define V8_DEBUG_AGENT_H_
-#ifdef ENABLE_DEBUGGER_SUPPORT
#include "../include/v8-debug.h"
#include "platform.h"
@@ -114,6 +90,4 @@ class DebuggerAgentUtil {
} } // namespace v8::internal
-#endif // ENABLE_DEBUGGER_SUPPORT
-
#endif // V8_DEBUG_AGENT_H_
diff --git a/deps/v8/src/debug-debugger.js b/deps/v8/src/debug-debugger.js
index b159ae3b29..0ce88328ba 100644
--- a/deps/v8/src/debug-debugger.js
+++ b/deps/v8/src/debug-debugger.js
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Default number of frames to include in the response to backtrace request.
var kDefaultBacktraceLength = 10;
@@ -1093,15 +1070,16 @@ BreakEvent.prototype.toJSONProtocol = function() {
};
-function MakeExceptionEvent(exec_state, exception, uncaught) {
- return new ExceptionEvent(exec_state, exception, uncaught);
+function MakeExceptionEvent(exec_state, exception, uncaught, promise) {
+ return new ExceptionEvent(exec_state, exception, uncaught, promise);
}
-function ExceptionEvent(exec_state, exception, uncaught) {
+function ExceptionEvent(exec_state, exception, uncaught, promise) {
this.exec_state_ = exec_state;
this.exception_ = exception;
this.uncaught_ = uncaught;
+ this.promise_ = promise;
}
@@ -1125,6 +1103,11 @@ ExceptionEvent.prototype.uncaught = function() {
};
+ExceptionEvent.prototype.promise = function() {
+ return this.promise_;
+};
+
+
ExceptionEvent.prototype.func = function() {
return this.exec_state_.frame(0).func();
};
@@ -1217,31 +1200,6 @@ CompileEvent.prototype.toJSONProtocol = function() {
};
-function MakeNewFunctionEvent(func) {
- return new NewFunctionEvent(func);
-}
-
-
-function NewFunctionEvent(func) {
- this.func = func;
-}
-
-
-NewFunctionEvent.prototype.eventType = function() {
- return Debug.DebugEvent.NewFunction;
-};
-
-
-NewFunctionEvent.prototype.name = function() {
- return this.func.name;
-};
-
-
-NewFunctionEvent.prototype.setBreakPoint = function(p) {
- Debug.setBreakPoint(this.func, p || 0);
-};
-
-
function MakeScriptCollectedEvent(exec_state, id) {
return new ScriptCollectedEvent(exec_state, id);
}
diff --git a/deps/v8/src/debug.cc b/deps/v8/src/debug.cc
index d7667f19c8..3ecf8bada7 100644
--- a/deps/v8/src/debug.cc
+++ b/deps/v8/src/debug.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -53,9 +30,6 @@
namespace v8 {
namespace internal {
-#ifdef ENABLE_DEBUGGER_SUPPORT
-
-
Debug::Debug(Isolate* isolate)
: has_break_points_(false),
script_cache_(NULL),
@@ -63,10 +37,11 @@ Debug::Debug(Isolate* isolate)
disable_break_(false),
break_on_exception_(false),
break_on_uncaught_exception_(false),
- debug_break_return_(NULL),
- debug_break_slot_(NULL),
+ promise_catch_handlers_(0),
+ promise_getters_(0),
isolate_(isolate) {
memset(registers_, 0, sizeof(JSCallerSavedBuffer));
+ ThreadInit();
}
@@ -406,6 +381,7 @@ bool BreakLocationIterator::IsStepInLocation(Isolate* isolate) {
if (target_code->kind() == Code::STUB) {
return target_code->major_key() == CodeStub::CallFunction;
}
+ return target_code->is_call_stub();
}
return false;
}
@@ -688,21 +664,6 @@ void ScriptCache::HandleWeakScript(
}
-void Debug::SetUp(bool create_heap_objects) {
- ThreadInit();
- if (create_heap_objects) {
- // Get code to handle debug break on return.
- debug_break_return_ =
- isolate_->builtins()->builtin(Builtins::kReturn_DebugBreak);
- ASSERT(debug_break_return_->IsCode());
- // Get code to handle debug break in debug break slots.
- debug_break_slot_ =
- isolate_->builtins()->builtin(Builtins::kSlot_DebugBreak);
- ASSERT(debug_break_slot_->IsCode());
- }
-}
-
-
void Debug::HandleWeakDebugInfo(
const v8::WeakCallbackData<v8::Value, void>& data) {
Debug* debug = reinterpret_cast<Isolate*>(data.GetIsolate())->debug();
@@ -753,8 +714,8 @@ bool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
Handle<String> source_code =
isolate->bootstrapper()->NativesSourceLookup(index);
Vector<const char> name = Natives::GetScriptName(index);
- Handle<String> script_name = factory->NewStringFromAscii(name);
- ASSERT(!script_name.is_null());
+ Handle<String> script_name =
+ factory->NewStringFromAscii(name).ToHandleChecked();
Handle<Context> context = isolate->native_context();
// Compile the script.
@@ -774,19 +735,19 @@ bool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
}
// Execute the shared function in the debugger context.
- bool caught_exception;
Handle<JSFunction> function =
factory->NewFunctionFromSharedFunctionInfo(function_info, context);
- Handle<Object> exception =
+ Handle<Object> exception;
+ MaybeHandle<Object> result =
Execution::TryCall(function,
Handle<Object>(context->global_object(), isolate),
0,
NULL,
- &caught_exception);
+ &exception);
// Check for caught exceptions.
- if (caught_exception) {
+ if (result.is_null()) {
ASSERT(!isolate->has_pending_exception());
MessageLocation computed_location;
isolate->ComputeLocation(&computed_location);
@@ -847,7 +808,7 @@ bool Debug::Load() {
Handle<String> key = isolate_->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("builtins"));
Handle<GlobalObject> global = Handle<GlobalObject>(context->global_object());
- RETURN_IF_EMPTY_HANDLE_VALUE(
+ RETURN_ON_EXCEPTION_VALUE(
isolate_,
JSReceiver::SetProperty(global,
key,
@@ -906,12 +867,6 @@ void Debug::PreemptionWhileInDebugger() {
}
-void Debug::Iterate(ObjectVisitor* v) {
- v->VisitPointer(BitCast<Object**>(&(debug_break_return_)));
- v->VisitPointer(BitCast<Object**>(&(debug_break_slot_)));
-}
-
-
Object* Debug::Break(Arguments args) {
Heap* heap = isolate_->heap();
HandleScope scope(isolate_);
@@ -1061,7 +1016,7 @@ Object* Debug::Break(Arguments args) {
}
-RUNTIME_FUNCTION(Object*, Debug_Break) {
+RUNTIME_FUNCTION(Debug_Break) {
return isolate->debug()->Break(args);
}
@@ -1116,31 +1071,26 @@ bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
Handle<String> is_break_point_triggered_string =
factory->InternalizeOneByteString(
STATIC_ASCII_VECTOR("IsBreakPointTriggered"));
+ Handle<GlobalObject> debug_global(debug_context()->global_object());
Handle<JSFunction> check_break_point =
- Handle<JSFunction>(JSFunction::cast(
- debug_context()->global_object()->GetPropertyNoExceptionThrown(
- *is_break_point_triggered_string)));
+ Handle<JSFunction>::cast(Object::GetProperty(
+ debug_global, is_break_point_triggered_string).ToHandleChecked());
// Get the break id as an object.
Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id());
// Call HandleBreakPointx.
- bool caught_exception;
Handle<Object> argv[] = { break_id, break_point_object };
- Handle<Object> result = Execution::TryCall(check_break_point,
- isolate_->js_builtins_object(),
- ARRAY_SIZE(argv),
- argv,
- &caught_exception);
-
- // If exception or non boolean result handle as not triggered
- if (caught_exception || !result->IsBoolean()) {
+ Handle<Object> result;
+ if (!Execution::TryCall(check_break_point,
+ isolate_->js_builtins_object(),
+ ARRAY_SIZE(argv),
+ argv).ToHandle(&result)) {
return false;
}
// Return whether the break point is triggered.
- ASSERT(!result.is_null());
- return (*result)->IsTrue();
+ return result->IsTrue();
}
@@ -1348,6 +1298,53 @@ bool Debug::IsBreakOnException(ExceptionBreakType type) {
}
+void Debug::PromiseHandlePrologue(Handle<JSFunction> promise_getter) {
+ Handle<JSFunction> promise_getter_global = Handle<JSFunction>::cast(
+ isolate_->global_handles()->Create(*promise_getter));
+ StackHandler* handler =
+ StackHandler::FromAddress(Isolate::handler(isolate_->thread_local_top()));
+ promise_getters_.Add(promise_getter_global);
+ promise_catch_handlers_.Add(handler);
+}
+
+
+void Debug::PromiseHandleEpilogue() {
+ if (promise_catch_handlers_.length() == 0) return;
+ promise_catch_handlers_.RemoveLast();
+ Handle<Object> promise_getter = promise_getters_.RemoveLast();
+ isolate_->global_handles()->Destroy(promise_getter.location());
+}
+
+
+Handle<Object> Debug::GetPromiseForUncaughtException() {
+ Handle<Object> undefined = isolate_->factory()->undefined_value();
+ if (promise_getters_.length() == 0) return undefined;
+ Handle<JSFunction> promise_getter = promise_getters_.last();
+ StackHandler* promise_catch = promise_catch_handlers_.last();
+ // Find the top-most try-catch handler.
+ StackHandler* handler = StackHandler::FromAddress(
+ Isolate::handler(isolate_->thread_local_top()));
+ while (handler != NULL && !handler->is_catch()) {
+ handler = handler->next();
+ }
+#ifdef DEBUG
+ // Make sure that our promise catch handler is in the list of handlers,
+ // even if it's not the top-most try-catch handler.
+ StackHandler* temp = handler;
+ while (temp != promise_catch && !temp->is_catch()) {
+ temp = temp->next();
+ CHECK(temp != NULL);
+ }
+#endif // DEBUG
+
+ if (handler == promise_catch) {
+ return Execution::Call(
+ isolate_, promise_getter, undefined, 0, NULL).ToHandleChecked();
+ }
+ return undefined;
+}
+
+
void Debug::PrepareStep(StepAction step_action,
int step_count,
StackFrame::Id frame_id) {
@@ -1425,6 +1422,9 @@ void Debug::PrepareStep(StepAction step_action,
bool is_call_target = false;
Address target = it.rinfo()->target_address();
Code* code = Code::GetCodeFromTargetAddress(target);
+ if (code->is_call_stub()) {
+ is_call_target = true;
+ }
if (code->is_inline_cache_stub()) {
is_inline_cache_stub = true;
is_load_or_store = !is_call_target;
@@ -1439,8 +1439,9 @@ void Debug::PrepareStep(StepAction step_action,
maybe_call_function_stub =
Code::GetCodeFromTargetAddress(original_target);
}
- if (maybe_call_function_stub->kind() == Code::STUB &&
- maybe_call_function_stub->major_key() == CodeStub::CallFunction) {
+ if ((maybe_call_function_stub->kind() == Code::STUB &&
+ maybe_call_function_stub->major_key() == CodeStub::CallFunction) ||
+ maybe_call_function_stub->kind() == Code::CALL_IC) {
// Save reference to the code as we may need it to find out arguments
// count for 'step in' later.
call_function_stub = Handle<Code>(maybe_call_function_stub);
@@ -1496,6 +1497,7 @@ void Debug::PrepareStep(StepAction step_action,
} else if (!call_function_stub.is_null()) {
// If it's CallFunction stub ensure target function is compiled and flood
// it with one shot breakpoints.
+ bool is_call_ic = call_function_stub->kind() == Code::CALL_IC;
// Find out number of arguments from the stub minor key.
// Reverse lookup required as the minor key cannot be retrieved
@@ -1511,11 +1513,13 @@ void Debug::PrepareStep(StepAction step_action,
uint32_t key = Smi::cast(*obj)->value();
// Argc in the stub is the number of arguments passed - not the
// expected arguments of the called function.
- int call_function_arg_count =
- CallFunctionStub::ExtractArgcFromMinorKey(
+ int call_function_arg_count = is_call_ic
+ ? CallICStub::ExtractArgcFromMinorKey(CodeStub::MinorKeyFromKey(key))
+ : CallFunctionStub::ExtractArgcFromMinorKey(
CodeStub::MinorKeyFromKey(key));
- ASSERT(call_function_stub->major_key() ==
- CodeStub::MajorKeyFromKey(key));
+
+ ASSERT(is_call_ic ||
+ call_function_stub->major_key() == CodeStub::MajorKeyFromKey(key));
// Find target function on the expression stack.
// Expression stack looks like this (top to bottom):
@@ -1643,6 +1647,9 @@ Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) {
// used by the call site.
if (code->is_inline_cache_stub()) {
switch (code->kind()) {
+ case Code::CALL_IC:
+ return isolate->builtins()->CallICStub_DebugBreak();
+
case Code::LOAD_IC:
return isolate->builtins()->LoadIC_DebugBreak();
@@ -1671,11 +1678,7 @@ Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) {
}
if (code->kind() == Code::STUB) {
ASSERT(code->major_key() == CodeStub::CallFunction);
- if (code->has_function_cache()) {
- return isolate->builtins()->CallFunctionStub_Recording_DebugBreak();
- } else {
- return isolate->builtins()->CallFunctionStub_DebugBreak();
- }
+ return isolate->builtins()->CallFunctionStub_DebugBreak();
}
UNREACHABLE();
@@ -1878,6 +1881,59 @@ static void CollectActiveFunctionsFromThread(
}
+// Figure out how many bytes of "pc_offset" correspond to actual code by
+// subtracting off the bytes that correspond to constant/veneer pools. See
+// Assembler::CheckConstPool() and Assembler::CheckVeneerPool(). Note that this
+// is only useful for architectures using constant pools or veneer pools.
+static int ComputeCodeOffsetFromPcOffset(Code *code, int pc_offset) {
+ ASSERT_EQ(code->kind(), Code::FUNCTION);
+ ASSERT(!code->has_debug_break_slots());
+ ASSERT_LE(0, pc_offset);
+ ASSERT_LT(pc_offset, code->instruction_end() - code->instruction_start());
+
+ int mask = RelocInfo::ModeMask(RelocInfo::CONST_POOL) |
+ RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
+ byte *pc = code->instruction_start() + pc_offset;
+ int code_offset = pc_offset;
+ for (RelocIterator it(code, mask); !it.done(); it.next()) {
+ RelocInfo* info = it.rinfo();
+ if (info->pc() >= pc) break;
+ ASSERT(RelocInfo::IsConstPool(info->rmode()));
+ code_offset -= static_cast<int>(info->data());
+ ASSERT_LE(0, code_offset);
+ }
+
+ return code_offset;
+}
+
+
+// The inverse of ComputeCodeOffsetFromPcOffset.
+static int ComputePcOffsetFromCodeOffset(Code *code, int code_offset) {
+ ASSERT_EQ(code->kind(), Code::FUNCTION);
+
+ int mask = RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) |
+ RelocInfo::ModeMask(RelocInfo::CONST_POOL) |
+ RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
+ int reloc = 0;
+ for (RelocIterator it(code, mask); !it.done(); it.next()) {
+ RelocInfo* info = it.rinfo();
+ if (info->pc() - code->instruction_start() - reloc >= code_offset) break;
+ if (RelocInfo::IsDebugBreakSlot(info->rmode())) {
+ reloc += Assembler::kDebugBreakSlotLength;
+ } else {
+ ASSERT(RelocInfo::IsConstPool(info->rmode()));
+ reloc += static_cast<int>(info->data());
+ }
+ }
+
+ int pc_offset = code_offset + reloc;
+
+ ASSERT_LT(code->instruction_start() + pc_offset, code->instruction_end());
+
+ return pc_offset;
+}
+
+
static void RedirectActivationsToRecompiledCodeOnThread(
Isolate* isolate,
ThreadLocalTop* top) {
@@ -1899,51 +1955,13 @@ static void RedirectActivationsToRecompiledCodeOnThread(
continue;
}
- // Iterate over the RelocInfo in the original code to compute the sum of the
- // constant pools and veneer pools sizes. (See Assembler::CheckConstPool()
- // and Assembler::CheckVeneerPool())
- // Note that this is only useful for architectures using constant pools or
- // veneer pools.
- int pool_mask = RelocInfo::ModeMask(RelocInfo::CONST_POOL) |
- RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
- int frame_pool_size = 0;
- for (RelocIterator it(*frame_code, pool_mask); !it.done(); it.next()) {
- RelocInfo* info = it.rinfo();
- if (info->pc() >= frame->pc()) break;
- frame_pool_size += static_cast<int>(info->data());
- }
- intptr_t frame_offset =
- frame->pc() - frame_code->instruction_start() - frame_pool_size;
-
- // Iterate over the RelocInfo for new code to find the number of bytes
- // generated for debug slots and constant pools.
- int debug_break_slot_bytes = 0;
- int new_code_pool_size = 0;
- int mask = RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) |
- RelocInfo::ModeMask(RelocInfo::CONST_POOL) |
- RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
- for (RelocIterator it(*new_code, mask); !it.done(); it.next()) {
- // Check if the pc in the new code with debug break
- // slots is before this slot.
- RelocInfo* info = it.rinfo();
- intptr_t new_offset = info->pc() - new_code->instruction_start() -
- new_code_pool_size - debug_break_slot_bytes;
- if (new_offset >= frame_offset) {
- break;
- }
-
- if (RelocInfo::IsDebugBreakSlot(info->rmode())) {
- debug_break_slot_bytes += Assembler::kDebugBreakSlotLength;
- } else {
- ASSERT(RelocInfo::IsConstPool(info->rmode()));
- // The size of the pools is encoded in the data.
- new_code_pool_size += static_cast<int>(info->data());
- }
- }
+ int old_pc_offset =
+ static_cast<int>(frame->pc() - frame_code->instruction_start());
+ int code_offset = ComputeCodeOffsetFromPcOffset(*frame_code, old_pc_offset);
+ int new_pc_offset = ComputePcOffsetFromCodeOffset(*new_code, code_offset);
// Compute the equivalent pc in the new code.
- byte* new_pc = new_code->instruction_start() + frame_offset +
- debug_break_slot_bytes + new_code_pool_size;
+ byte* new_pc = new_code->instruction_start() + new_pc_offset;
if (FLAG_trace_deopt) {
PrintF("Replacing code %08" V8PRIxPTR " - %08" V8PRIxPTR " (%d) "
@@ -1999,6 +2017,55 @@ class ActiveFunctionsRedirector : public ThreadVisitor {
};
+class ForceDebuggerActive {
+ public:
+ explicit ForceDebuggerActive(Isolate *isolate) {
+ isolate_ = isolate;
+ old_state_ = isolate->debugger()->force_debugger_active();
+ isolate_->debugger()->set_force_debugger_active(true);
+ }
+
+ ~ForceDebuggerActive() {
+ isolate_->debugger()->set_force_debugger_active(old_state_);
+ }
+
+ private:
+ Isolate *isolate_;
+ bool old_state_;
+
+ DISALLOW_COPY_AND_ASSIGN(ForceDebuggerActive);
+};
+
+
+void Debug::MaybeRecompileFunctionForDebugging(Handle<JSFunction> function) {
+ ASSERT_EQ(Code::FUNCTION, function->code()->kind());
+ ASSERT_EQ(function->code(), function->shared()->code());
+
+ if (function->code()->has_debug_break_slots()) return;
+
+ ForceDebuggerActive force_debugger_active(isolate_);
+ MaybeHandle<Code> code = Compiler::GetCodeForDebugging(function);
+ // Recompilation can fail. In that case leave the code as it was.
+ if (!code.is_null())
+ function->ReplaceCode(*code.ToHandleChecked());
+ ASSERT_EQ(function->code(), function->shared()->code());
+}
+
+
+void Debug::RecompileAndRelocateSuspendedGenerators(
+ const List<Handle<JSGeneratorObject> > &generators) {
+ for (int i = 0; i < generators.length(); i++) {
+ Handle<JSFunction> fun(generators[i]->function());
+
+ MaybeRecompileFunctionForDebugging(fun);
+
+ int code_offset = generators[i]->continuation();
+ int pc_offset = ComputePcOffsetFromCodeOffset(fun->code(), code_offset);
+ generators[i]->set_continuation(pc_offset);
+ }
+}
+
+
void Debug::PrepareForBreakPoints() {
// If preparing for the first break point make sure to deoptimize all
// functions as debugging does not work with optimized code.
@@ -2018,6 +2085,21 @@ void Debug::PrepareForBreakPoints() {
// is used both in GC and non-GC code.
List<Handle<JSFunction> > active_functions(100);
+ // A list of all suspended generators.
+ List<Handle<JSGeneratorObject> > suspended_generators;
+
+ // A list of all generator functions. We need to recompile all functions,
+ // but we don't know until after visiting the whole heap which generator
+ // functions have suspended activations and which do not. As in the case of
+ // functions with activations on the stack, we need to be careful with
+ // generator functions with suspended activations because although they
+ // should be recompiled, recompilation can fail, and we need to avoid
+ // leaving the heap in an inconsistent state.
+ //
+ // We could perhaps avoid this list and instead re-use the GC metadata
+ // links.
+ List<Handle<JSFunction> > generator_functions;
+
{
// We are going to iterate heap to find all functions without
// debug break slots.
@@ -2055,6 +2137,11 @@ void Debug::PrepareForBreakPoints() {
if (function->IsBuiltin()) continue;
if (shared->code()->gc_metadata() == active_code_marker) continue;
+ if (shared->is_generator()) {
+ generator_functions.Add(Handle<JSFunction>(function, isolate_));
+ continue;
+ }
+
Code::Kind kind = function->code()->kind();
if (kind == Code::FUNCTION &&
!function->code()->has_debug_break_slots()) {
@@ -2074,6 +2161,24 @@ void Debug::PrepareForBreakPoints() {
function->shared()->set_code(*lazy_compile);
}
}
+ } else if (obj->IsJSGeneratorObject()) {
+ JSGeneratorObject* gen = JSGeneratorObject::cast(obj);
+ if (!gen->is_suspended()) continue;
+
+ JSFunction* fun = gen->function();
+ ASSERT_EQ(fun->code()->kind(), Code::FUNCTION);
+ if (fun->code()->has_debug_break_slots()) continue;
+
+ int pc_offset = gen->continuation();
+ ASSERT_LT(0, pc_offset);
+
+ int code_offset =
+ ComputeCodeOffsetFromPcOffset(fun->code(), pc_offset);
+
+ // This will be fixed after we recompile the functions.
+ gen->set_continuation(code_offset);
+
+ suspended_generators.Add(Handle<JSGeneratorObject>(gen, isolate_));
}
}
@@ -2084,41 +2189,35 @@ void Debug::PrepareForBreakPoints() {
}
}
+ // Recompile generator functions that have suspended activations, and
+ // relocate those activations.
+ RecompileAndRelocateSuspendedGenerators(suspended_generators);
+
+ // Mark generator functions that didn't have suspended activations for lazy
+ // recompilation. Note that this set does not include any active functions.
+ for (int i = 0; i < generator_functions.length(); i++) {
+ Handle<JSFunction> &function = generator_functions[i];
+ if (function->code()->kind() != Code::FUNCTION) continue;
+ if (function->code()->has_debug_break_slots()) continue;
+ function->set_code(*lazy_compile);
+ function->shared()->set_code(*lazy_compile);
+ }
+
// Now recompile all functions with activation frames and and
- // patch the return address to run in the new compiled code.
+ // patch the return address to run in the new compiled code. It could be
+ // that some active functions were recompiled already by the suspended
+ // generator recompilation pass above; a generator with suspended
+ // activations could also have active activations. That's fine.
for (int i = 0; i < active_functions.length(); i++) {
Handle<JSFunction> function = active_functions[i];
Handle<SharedFunctionInfo> shared(function->shared());
- if (function->code()->kind() == Code::FUNCTION &&
- function->code()->has_debug_break_slots()) {
- // Nothing to do. Function code already had debug break slots.
- continue;
- }
-
// If recompilation is not possible just skip it.
- if (shared->is_toplevel() ||
- !shared->allows_lazy_compilation() ||
- shared->code()->kind() == Code::BUILTIN) {
- continue;
- }
-
- // Make sure that the shared full code is compiled with debug
- // break slots.
- if (!shared->code()->has_debug_break_slots()) {
- // Try to compile the full code with debug break slots. If it
- // fails just keep the current code.
- bool prev_force_debugger_active =
- isolate_->debugger()->force_debugger_active();
- isolate_->debugger()->set_force_debugger_active(true);
- Handle<Code> code = Compiler::GetCodeForDebugging(function);
- function->ReplaceCode(*code);
- isolate_->debugger()->set_force_debugger_active(
- prev_force_debugger_active);
- }
+ if (shared->is_toplevel()) continue;
+ if (!shared->allows_lazy_compilation()) continue;
+ if (shared->code()->kind() == Code::BUILTIN) continue;
- // Keep function code in sync with shared function info.
- function->set_code(shared->code());
+ MaybeRecompileFunctionForDebugging(function);
}
RedirectActivationsToRecompiledCodeOnThread(isolate_,
@@ -2227,10 +2326,10 @@ Object* Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
// will compile all inner functions that cannot be compiled without a
// context, because Compiler::BuildFunctionInfo checks whether the
// debugger is active.
- Handle<Code> result = target_function.is_null()
+ MaybeHandle<Code> maybe_result = target_function.is_null()
? Compiler::GetUnoptimizedCode(target)
: Compiler::GetUnoptimizedCode(target_function);
- if (result.is_null()) return isolate_->heap()->undefined_value();
+ if (maybe_result.is_null()) return isolate_->heap()->undefined_value();
}
} // End while loop.
@@ -2463,14 +2562,14 @@ void Debug::ClearMirrorCache() {
// Clear the mirror cache.
Handle<String> function_name = isolate_->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("ClearMirrorCache"));
- Handle<Object> fun(
- isolate_->global_object()->GetPropertyNoExceptionThrown(*function_name),
- isolate_);
+ Handle<Object> fun = Object::GetProperty(
+ isolate_->global_object(), function_name).ToHandleChecked();
ASSERT(fun->IsJSFunction());
- bool caught_exception;
- Execution::TryCall(Handle<JSFunction>::cast(fun),
+ Execution::TryCall(
+ Handle<JSFunction>::cast(fun),
Handle<JSObject>(Debug::debug_context()->global_object()),
- 0, NULL, &caught_exception);
+ 0,
+ NULL);
}
@@ -2591,113 +2690,82 @@ Debugger::Debugger(Isolate* isolate)
Debugger::~Debugger() {}
-Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name,
- int argc,
- Handle<Object> argv[],
- bool* caught_exception) {
+MaybeHandle<Object> Debugger::MakeJSObject(
+ Vector<const char> constructor_name,
+ int argc,
+ Handle<Object> argv[]) {
ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
// Create the execution state object.
Handle<String> constructor_str =
isolate_->factory()->InternalizeUtf8String(constructor_name);
ASSERT(!constructor_str.is_null());
- Handle<Object> constructor(
- isolate_->global_object()->GetPropertyNoExceptionThrown(*constructor_str),
- isolate_);
+ Handle<Object> constructor = Object::GetProperty(
+ isolate_->global_object(), constructor_str).ToHandleChecked();
ASSERT(constructor->IsJSFunction());
- if (!constructor->IsJSFunction()) {
- *caught_exception = true;
- return isolate_->factory()->undefined_value();
- }
- Handle<Object> js_object = Execution::TryCall(
+ if (!constructor->IsJSFunction()) return MaybeHandle<Object>();
+ return Execution::TryCall(
Handle<JSFunction>::cast(constructor),
Handle<JSObject>(isolate_->debug()->debug_context()->global_object()),
argc,
- argv,
- caught_exception);
- return js_object;
+ argv);
}
-Handle<Object> Debugger::MakeExecutionState(bool* caught_exception) {
+MaybeHandle<Object> Debugger::MakeExecutionState() {
// Create the execution state object.
Handle<Object> break_id = isolate_->factory()->NewNumberFromInt(
isolate_->debug()->break_id());
Handle<Object> argv[] = { break_id };
- return MakeJSObject(CStrVector("MakeExecutionState"),
- ARRAY_SIZE(argv),
- argv,
- caught_exception);
+ return MakeJSObject(CStrVector("MakeExecutionState"), ARRAY_SIZE(argv), argv);
}
-Handle<Object> Debugger::MakeBreakEvent(Handle<Object> exec_state,
- Handle<Object> break_points_hit,
- bool* caught_exception) {
+MaybeHandle<Object> Debugger::MakeBreakEvent(Handle<Object> break_points_hit) {
+ Handle<Object> exec_state;
+ if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
// Create the new break event object.
Handle<Object> argv[] = { exec_state, break_points_hit };
- return MakeJSObject(CStrVector("MakeBreakEvent"),
- ARRAY_SIZE(argv),
- argv,
- caught_exception);
+ return MakeJSObject(CStrVector("MakeBreakEvent"), ARRAY_SIZE(argv), argv);
}
-Handle<Object> Debugger::MakeExceptionEvent(Handle<Object> exec_state,
- Handle<Object> exception,
- bool uncaught,
- bool* caught_exception) {
- Factory* factory = isolate_->factory();
+MaybeHandle<Object> Debugger::MakeExceptionEvent(Handle<Object> exception,
+ bool uncaught,
+ Handle<Object> promise) {
+ Handle<Object> exec_state;
+ if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
// Create the new exception event object.
Handle<Object> argv[] = { exec_state,
exception,
- factory->ToBoolean(uncaught) };
- return MakeJSObject(CStrVector("MakeExceptionEvent"),
- ARRAY_SIZE(argv),
- argv,
- caught_exception);
+ isolate_->factory()->ToBoolean(uncaught),
+ promise };
+ return MakeJSObject(CStrVector("MakeExceptionEvent"), ARRAY_SIZE(argv), argv);
}
-Handle<Object> Debugger::MakeNewFunctionEvent(Handle<Object> function,
- bool* caught_exception) {
- // Create the new function event object.
- Handle<Object> argv[] = { function };
- return MakeJSObject(CStrVector("MakeNewFunctionEvent"),
- ARRAY_SIZE(argv),
- argv,
- caught_exception);
-}
-
-
-Handle<Object> Debugger::MakeCompileEvent(Handle<Script> script,
- bool before,
- bool* caught_exception) {
- Factory* factory = isolate_->factory();
+MaybeHandle<Object> Debugger::MakeCompileEvent(Handle<Script> script,
+ bool before) {
+ Handle<Object> exec_state;
+ if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
// Create the compile event object.
- Handle<Object> exec_state = MakeExecutionState(caught_exception);
- Handle<Object> script_wrapper = GetScriptWrapper(script);
+ Handle<Object> script_wrapper = Script::GetWrapper(script);
Handle<Object> argv[] = { exec_state,
script_wrapper,
- factory->ToBoolean(before) };
- return MakeJSObject(CStrVector("MakeCompileEvent"),
- ARRAY_SIZE(argv),
- argv,
- caught_exception);
+ isolate_->factory()->ToBoolean(before) };
+ return MakeJSObject(CStrVector("MakeCompileEvent"), ARRAY_SIZE(argv), argv);
}
-Handle<Object> Debugger::MakeScriptCollectedEvent(int id,
- bool* caught_exception) {
+MaybeHandle<Object> Debugger::MakeScriptCollectedEvent(int id) {
+ Handle<Object> exec_state;
+ if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
// Create the script collected event object.
- Handle<Object> exec_state = MakeExecutionState(caught_exception);
Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_);
Handle<Object> argv[] = { exec_state, id_object };
- return MakeJSObject(CStrVector("MakeScriptCollectedEvent"),
- ARRAY_SIZE(argv),
- argv,
- caught_exception);
+ return MakeJSObject(
+ CStrVector("MakeScriptCollectedEvent"), ARRAY_SIZE(argv), argv);
}
@@ -2709,6 +2777,9 @@ void Debugger::OnException(Handle<Object> exception, bool uncaught) {
if (debug->InDebugger()) return;
if (!Debugger::EventActive(v8::Exception)) return;
+ Handle<Object> promise = debug->GetPromiseForUncaughtException();
+ uncaught |= !promise->IsUndefined();
+
// Bail out if exception breaks are not active
if (uncaught) {
// Uncaught exceptions are reported by either flags.
@@ -2725,16 +2796,12 @@ void Debugger::OnException(Handle<Object> exception, bool uncaught) {
// Clear all current stepping setup.
debug->ClearStepping();
+
// Create the event data object.
- bool caught_exception = false;
- Handle<Object> exec_state = MakeExecutionState(&caught_exception);
Handle<Object> event_data;
- if (!caught_exception) {
- event_data = MakeExceptionEvent(exec_state, exception, uncaught,
- &caught_exception);
- }
// Bail out and don't call debugger if exception.
- if (caught_exception) {
+ if (!MakeExceptionEvent(
+ exception, uncaught, promise).ToHandle(&event_data)) {
return;
}
@@ -2758,17 +2825,9 @@ void Debugger::OnDebugBreak(Handle<Object> break_points_hit,
ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
// Create the event data object.
- bool caught_exception = false;
- Handle<Object> exec_state = MakeExecutionState(&caught_exception);
Handle<Object> event_data;
- if (!caught_exception) {
- event_data = MakeBreakEvent(exec_state, break_points_hit,
- &caught_exception);
- }
// Bail out and don't call debugger if exception.
- if (caught_exception) {
- return;
- }
+ if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return;
// Process debug event.
ProcessDebugEvent(v8::Break,
@@ -2790,12 +2849,9 @@ void Debugger::OnBeforeCompile(Handle<Script> script) {
if (debugger.FailedToEnter()) return;
// Create the event data object.
- bool caught_exception = false;
- Handle<Object> event_data = MakeCompileEvent(script, true, &caught_exception);
+ Handle<Object> event_data;
// Bail out and don't call debugger if exception.
- if (caught_exception) {
- return;
- }
+ if (!MakeCompileEvent(script, true).ToHandle(&event_data)) return;
// Process debug event.
ProcessDebugEvent(v8::BeforeCompile,
@@ -2833,11 +2889,10 @@ void Debugger::OnAfterCompile(Handle<Script> script,
Handle<String> update_script_break_points_string =
isolate_->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("UpdateScriptBreakPoints"));
+ Handle<GlobalObject> debug_global(debug->debug_context()->global_object());
Handle<Object> update_script_break_points =
- Handle<Object>(
- debug->debug_context()->global_object()->GetPropertyNoExceptionThrown(
- *update_script_break_points_string),
- isolate_);
+ Object::GetProperty(
+ debug_global, update_script_break_points_string).ToHandleChecked();
if (!update_script_break_points->IsJSFunction()) {
return;
}
@@ -2845,17 +2900,14 @@ void Debugger::OnAfterCompile(Handle<Script> script,
// Wrap the script object in a proper JS object before passing it
// to JavaScript.
- Handle<JSValue> wrapper = GetScriptWrapper(script);
+ Handle<Object> wrapper = Script::GetWrapper(script);
// Call UpdateScriptBreakPoints expect no exceptions.
- bool caught_exception;
Handle<Object> argv[] = { wrapper };
- Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points),
- isolate_->js_builtins_object(),
- ARRAY_SIZE(argv),
- argv,
- &caught_exception);
- if (caught_exception) {
+ if (Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points),
+ isolate_->js_builtins_object(),
+ ARRAY_SIZE(argv),
+ argv).is_null()) {
return;
}
// Bail out based on state or if there is no listener for this event
@@ -2863,17 +2915,12 @@ void Debugger::OnAfterCompile(Handle<Script> script,
if (!Debugger::EventActive(v8::AfterCompile)) return;
// Create the compile state object.
- Handle<Object> event_data = MakeCompileEvent(script,
- false,
- &caught_exception);
+ Handle<Object> event_data;
// Bail out and don't call debugger if exception.
- if (caught_exception) {
- return;
- }
+ if (!MakeCompileEvent(script, false).ToHandle(&event_data)) return;
+
// Process debug event.
- ProcessDebugEvent(v8::AfterCompile,
- Handle<JSObject>::cast(event_data),
- true);
+ ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true);
}
@@ -2890,13 +2937,9 @@ void Debugger::OnScriptCollected(int id) {
if (debugger.FailedToEnter()) return;
// Create the script collected state object.
- bool caught_exception = false;
- Handle<Object> event_data = MakeScriptCollectedEvent(id,
- &caught_exception);
+ Handle<Object> event_data;
// Bail out and don't call debugger if exception.
- if (caught_exception) {
- return;
- }
+ if (!MakeScriptCollectedEvent(id).ToHandle(&event_data)) return;
// Process debug event.
ProcessDebugEvent(v8::ScriptCollected,
@@ -2916,11 +2959,10 @@ void Debugger::ProcessDebugEvent(v8::DebugEvent event,
}
// Create the execution state.
- bool caught_exception = false;
- Handle<Object> exec_state = MakeExecutionState(&caught_exception);
- if (caught_exception) {
- return;
- }
+ Handle<Object> exec_state;
+ // Bail out and don't call debugger if exception.
+ if (!MakeExecutionState().ToHandle(&exec_state)) return;
+
// First notify the message handler if any.
if (message_handler_ != NULL) {
NotifyMessageHandler(event,
@@ -2991,12 +3033,10 @@ void Debugger::CallJSEventCallback(v8::DebugEvent event,
exec_state,
event_data,
event_listener_data_ };
- bool caught_exception;
Execution::TryCall(fun,
isolate_->global_object(),
ARRAY_SIZE(argv),
- argv,
- &caught_exception);
+ argv);
// Silently ignore exceptions from debug event listeners.
}
@@ -3248,7 +3288,8 @@ void Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) {
void Debugger::ListenersChanged() {
- if (IsDebuggerActive()) {
+ bool active = IsDebuggerActive();
+ if (active) {
// Disable the compilation cache when the debugger is active.
isolate_->compilation_cache()->Disable();
debugger_unload_pending_ = false;
@@ -3350,9 +3391,8 @@ bool Debugger::IsDebuggerActive() {
}
-Handle<Object> Debugger::Call(Handle<JSFunction> fun,
- Handle<Object> data,
- bool* pending_exception) {
+MaybeHandle<Object> Debugger::Call(Handle<JSFunction> fun,
+ Handle<Object> data) {
// When calling functions in the debugger prevent it from beeing unloaded.
Debugger::never_unload_debugger_ = true;
@@ -3363,22 +3403,19 @@ Handle<Object> Debugger::Call(Handle<JSFunction> fun,
}
// Create the execution state.
- bool caught_exception = false;
- Handle<Object> exec_state = MakeExecutionState(&caught_exception);
- if (caught_exception) {
+ Handle<Object> exec_state;
+ if (!MakeExecutionState().ToHandle(&exec_state)) {
return isolate_->factory()->undefined_value();
}
Handle<Object> argv[] = { exec_state, data };
- Handle<Object> result = Execution::Call(
+ return Execution::Call(
isolate_,
fun,
Handle<Object>(isolate_->debug()->debug_context_->global_proxy(),
isolate_),
ARRAY_SIZE(argv),
- argv,
- pending_exception);
- return result;
+ argv);
}
@@ -3397,7 +3434,7 @@ bool Debugger::StartAgent(const char* name, int port,
// Once become suspended, V8 will stay so indefinitely long, until remote
// debugger connects and issues "continue" command.
Debugger::message_handler_ = StubMessageHandler2;
- v8::Debug::DebugBreak();
+ v8::Debug::DebugBreak(reinterpret_cast<v8::Isolate*>(isolate_));
}
if (agent_ == NULL) {
@@ -3597,20 +3634,21 @@ v8::Handle<v8::Object> MessageImpl::GetEventData() const {
v8::Handle<v8::String> MessageImpl::GetJSON() const {
- v8::EscapableHandleScope scope(
- reinterpret_cast<v8::Isolate*>(event_data_->GetIsolate()));
+ Isolate* isolate = event_data_->GetIsolate();
+ v8::EscapableHandleScope scope(reinterpret_cast<v8::Isolate*>(isolate));
if (IsEvent()) {
// Call toJSONProtocol on the debug event object.
- Handle<Object> fun = GetProperty(event_data_, "toJSONProtocol");
+ Handle<Object> fun = Object::GetProperty(
+ isolate, event_data_, "toJSONProtocol").ToHandleChecked();
if (!fun->IsJSFunction()) {
return v8::Handle<v8::String>();
}
- bool caught_exception;
- Handle<Object> json = Execution::TryCall(Handle<JSFunction>::cast(fun),
- event_data_,
- 0, NULL, &caught_exception);
- if (caught_exception || !json->IsString()) {
+
+ MaybeHandle<Object> maybe_json =
+ Execution::TryCall(Handle<JSFunction>::cast(fun), event_data_, 0, NULL);
+ Handle<Object> json;
+ if (!maybe_json.ToHandle(&json) || !json->IsString()) {
return v8::Handle<v8::String>();
}
return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json)));
@@ -3815,6 +3853,4 @@ void MessageDispatchHelperThread::Run() {
}
}
-#endif // ENABLE_DEBUGGER_SUPPORT
-
} } // namespace v8::internal
diff --git a/deps/v8/src/debug.h b/deps/v8/src/debug.h
index 564f9e8854..457a5fad84 100644
--- a/deps/v8/src/debug.h
+++ b/deps/v8/src/debug.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_DEBUG_H_
#define V8_DEBUG_H_
@@ -41,7 +18,6 @@
#include "string-stream.h"
#include "v8threads.h"
-#ifdef ENABLE_DEBUGGER_SUPPORT
#include "../include/v8-debug.h"
namespace v8 {
@@ -175,7 +151,9 @@ class BreakLocationIterator {
class ScriptCache : private HashMap {
public:
explicit ScriptCache(Isolate* isolate)
- : HashMap(ScriptMatch), isolate_(isolate), collected_scripts_(10) {}
+ : HashMap(HashMap::PointersMatch),
+ isolate_(isolate),
+ collected_scripts_(10) {}
virtual ~ScriptCache() { Clear(); }
// Add script to the cache.
@@ -193,9 +171,6 @@ class ScriptCache : private HashMap {
return ComputeIntegerHash(key, v8::internal::kZeroHashSeed);
}
- // Scripts match if their keys (script id) match.
- static bool ScriptMatch(void* key1, void* key2) { return key1 == key2; }
-
// Clear the cache releasing all the weak handles.
void Clear();
@@ -237,13 +212,11 @@ class DebugInfoListNode {
// DebugInfo.
class Debug {
public:
- void SetUp(bool create_heap_objects);
bool Load();
void Unload();
bool IsLoaded() { return !debug_context_.is_null(); }
bool InDebugger() { return thread_local_.debugger_entry_ != NULL; }
void PreemptionWhileInDebugger();
- void Iterate(ObjectVisitor* v);
Object* Break(Arguments args);
void SetBreakPoint(Handle<JSFunction> function,
@@ -260,6 +233,12 @@ class Debug {
void FloodHandlerWithOneShot();
void ChangeBreakOnException(ExceptionBreakType type, bool enable);
bool IsBreakOnException(ExceptionBreakType type);
+
+ void PromiseHandlePrologue(Handle<JSFunction> promise_getter);
+ void PromiseHandleEpilogue();
+ // Returns a promise if it does not have a reject handler.
+ Handle<Object> GetPromiseForUncaughtException();
+
void PrepareStep(StepAction step_action,
int step_count,
StackFrame::Id frame_id);
@@ -366,8 +345,6 @@ class Debug {
enum AddressId {
k_after_break_target_address,
- k_debug_break_return_address,
- k_debug_break_slot_address,
k_restarter_frame_function_pointer
};
@@ -385,18 +362,6 @@ class Debug {
return &registers_[r];
}
- // Access to the debug break on return code.
- Code* debug_break_return() { return debug_break_return_; }
- Code** debug_break_return_address() {
- return &debug_break_return_;
- }
-
- // Access to the debug break in debug break slot code.
- Code* debug_break_slot() { return debug_break_slot_; }
- Code** debug_break_slot_address() {
- return &debug_break_slot_;
- }
-
static const int kEstimatedNofDebugInfoEntries = 16;
static const int kEstimatedNofBreakPointsInFunction = 16;
@@ -431,6 +396,7 @@ class Debug {
// Code generator routines.
static void GenerateSlot(MacroAssembler* masm);
+ static void GenerateCallICStubDebugBreak(MacroAssembler* masm);
static void GenerateLoadICDebugBreak(MacroAssembler* masm);
static void GenerateStoreICDebugBreak(MacroAssembler* masm);
static void GenerateKeyedLoadICDebugBreak(MacroAssembler* masm);
@@ -438,7 +404,6 @@ class Debug {
static void GenerateCompareNilICDebugBreak(MacroAssembler* masm);
static void GenerateReturnDebugBreak(MacroAssembler* masm);
static void GenerateCallFunctionStubDebugBreak(MacroAssembler* masm);
- static void GenerateCallFunctionStubRecordDebugBreak(MacroAssembler* masm);
static void GenerateCallConstructStubDebugBreak(MacroAssembler* masm);
static void GenerateCallConstructStubRecordDebugBreak(MacroAssembler* masm);
static void GenerateSlotDebugBreak(MacroAssembler* masm);
@@ -450,9 +415,6 @@ class Debug {
// called, it only gets returned to.
static void GenerateFrameDropperLiveEdit(MacroAssembler* masm);
- // Called from stub-cache.cc.
- static void GenerateCallICDebugBreak(MacroAssembler* masm);
-
// Describes how exactly a frame has been dropped from stack.
enum FrameDropMode {
// No frame has been dropped.
@@ -549,6 +511,10 @@ class Debug {
Handle<Object> CheckBreakPoints(Handle<Object> break_point);
bool CheckBreakPoint(Handle<Object> break_point_object);
+ void MaybeRecompileFunctionForDebugging(Handle<JSFunction> function);
+ void RecompileAndRelocateSuspendedGenerators(
+ const List<Handle<JSGeneratorObject> > &suspended_generators);
+
// Global handle to debug context where all the debugger JavaScript code is
// loaded.
Handle<Context> debug_context_;
@@ -566,6 +532,14 @@ class Debug {
bool break_on_exception_;
bool break_on_uncaught_exception_;
+ // When a promise is being resolved, we may want to trigger a debug event for
+ // the case we catch a throw. For this purpose we remember the try-catch
+ // handler address that would catch the exception. We also hold onto a
+ // closure that returns a promise if the exception is considered uncaught.
+ // Due to the possibility of reentry we use a list to form a stack.
+ List<StackHandler*> promise_catch_handlers_;
+ List<Handle<JSFunction> > promise_getters_;
+
// Per-thread data.
class ThreadLocal {
public:
@@ -624,12 +598,6 @@ class Debug {
ThreadLocal thread_local_;
void ThreadInit();
- // Code to call for handling debug break on return.
- Code* debug_break_return_;
-
- // Code to call for handling debug break in debug break slots.
- Code* debug_break_slot_;
-
Isolate* isolate_;
friend class Isolate;
@@ -638,7 +606,7 @@ class Debug {
};
-DECLARE_RUNTIME_FUNCTION(Object*, Debug_Break);
+DECLARE_RUNTIME_FUNCTION(Debug_Break);
// Message delivered to the message handler callback. This is either a debugger
@@ -786,25 +754,21 @@ class Debugger {
void DebugRequest(const uint16_t* json_request, int length);
- Handle<Object> MakeJSObject(Vector<const char> constructor_name,
- int argc,
- Handle<Object> argv[],
- bool* caught_exception);
- Handle<Object> MakeExecutionState(bool* caught_exception);
- Handle<Object> MakeBreakEvent(Handle<Object> exec_state,
- Handle<Object> break_points_hit,
- bool* caught_exception);
- Handle<Object> MakeExceptionEvent(Handle<Object> exec_state,
- Handle<Object> exception,
- bool uncaught,
- bool* caught_exception);
- Handle<Object> MakeNewFunctionEvent(Handle<Object> func,
- bool* caught_exception);
- Handle<Object> MakeCompileEvent(Handle<Script> script,
- bool before,
- bool* caught_exception);
- Handle<Object> MakeScriptCollectedEvent(int id,
- bool* caught_exception);
+ MUST_USE_RESULT MaybeHandle<Object> MakeJSObject(
+ Vector<const char> constructor_name,
+ int argc,
+ Handle<Object> argv[]);
+ MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState();
+ MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent(
+ Handle<Object> break_points_hit);
+ MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent(
+ Handle<Object> exception,
+ bool uncaught,
+ Handle<Object> promise);
+ MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
+ Handle<Script> script, bool before);
+ MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id);
+
void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
void OnException(Handle<Object> exception, bool uncaught);
void OnBeforeCompile(Handle<Script> script);
@@ -844,9 +808,8 @@ class Debugger {
// Enqueue a debugger command to the command queue for event listeners.
void EnqueueDebugCommand(v8::Debug::ClientData* client_data = NULL);
- Handle<Object> Call(Handle<JSFunction> fun,
- Handle<Object> data,
- bool* pending_exception);
+ MUST_USE_RESULT MaybeHandle<Object> Call(Handle<JSFunction> fun,
+ Handle<Object> data);
// Start the debugger agent listening on the provided port.
bool StartAgent(const char* name, int port,
@@ -1015,10 +978,6 @@ class Debug_Address {
return Debug_Address(Debug::k_after_break_target_address);
}
- static Debug_Address DebugBreakReturn() {
- return Debug_Address(Debug::k_debug_break_return_address);
- }
-
static Debug_Address RestarterFrameFunctionPointer() {
return Debug_Address(Debug::k_restarter_frame_function_pointer);
}
@@ -1028,10 +987,6 @@ class Debug_Address {
switch (id_) {
case Debug::k_after_break_target_address:
return reinterpret_cast<Address>(debug->after_break_target_address());
- case Debug::k_debug_break_return_address:
- return reinterpret_cast<Address>(debug->debug_break_return_address());
- case Debug::k_debug_break_slot_address:
- return reinterpret_cast<Address>(debug->debug_break_slot_address());
case Debug::k_restarter_frame_function_pointer:
return reinterpret_cast<Address>(
debug->restarter_frame_function_pointer_address());
@@ -1070,6 +1025,4 @@ class MessageDispatchHelperThread: public Thread {
} } // namespace v8::internal
-#endif // ENABLE_DEBUGGER_SUPPORT
-
#endif // V8_DEBUG_H_
diff --git a/deps/v8/src/deoptimizer.cc b/deps/v8/src/deoptimizer.cc
index 4d5e60573d..e8cf5993e6 100644
--- a/deps/v8/src/deoptimizer.cc
+++ b/deps/v8/src/deoptimizer.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -56,9 +33,7 @@ static MemoryChunk* AllocateCodeChunk(MemoryAllocator* allocator) {
DeoptimizerData::DeoptimizerData(MemoryAllocator* allocator)
: allocator_(allocator),
-#ifdef ENABLE_DEBUGGER_SUPPORT
deoptimized_frame_info_(NULL),
-#endif
current_(NULL) {
for (int i = 0; i < Deoptimizer::kBailoutTypesWithCodeEntry; ++i) {
deopt_entry_code_entries_[i] = -1;
@@ -75,13 +50,11 @@ DeoptimizerData::~DeoptimizerData() {
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
void DeoptimizerData::Iterate(ObjectVisitor* v) {
if (deoptimized_frame_info_ != NULL) {
deoptimized_frame_info_->Iterate(v);
}
}
-#endif
Code* Deoptimizer::FindDeoptimizingCode(Address addr) {
@@ -91,7 +64,7 @@ Code* Deoptimizer::FindDeoptimizingCode(Address addr) {
Object* element = native_context->DeoptimizedCodeListHead();
while (!element->IsUndefined()) {
Code* code = Code::cast(element);
- ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
+ CHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
if (code->contains(addr)) return code;
element = code->next_code_link();
}
@@ -115,7 +88,7 @@ Deoptimizer* Deoptimizer::New(JSFunction* function,
from,
fp_to_sp_delta,
NULL);
- ASSERT(isolate->deoptimizer_data()->current_ == NULL);
+ CHECK(isolate->deoptimizer_data()->current_ == NULL);
isolate->deoptimizer_data()->current_ = deoptimizer;
return deoptimizer;
}
@@ -137,7 +110,7 @@ size_t Deoptimizer::GetMaxDeoptTableSize() {
Deoptimizer* Deoptimizer::Grab(Isolate* isolate) {
Deoptimizer* result = isolate->deoptimizer_data()->current_;
- ASSERT(result != NULL);
+ CHECK_NE(result, NULL);
result->DeleteFrameDescriptions();
isolate->deoptimizer_data()->current_ = NULL;
return result;
@@ -160,13 +133,12 @@ int Deoptimizer::ConvertJSFrameIndexToFrameIndex(int jsframe_index) {
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
JavaScriptFrame* frame,
int jsframe_index,
Isolate* isolate) {
- ASSERT(frame->is_optimized());
- ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == NULL);
+ CHECK(frame->is_optimized());
+ CHECK(isolate->deoptimizer_data()->deoptimized_frame_info_ == NULL);
// Get the function and code from the frame.
JSFunction* function = frame->function();
@@ -176,7 +148,7 @@ DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
// return address must be at a place in the code with deoptimization support.
SafepointEntry safepoint_entry = code->GetSafepointEntry(frame->pc());
int deoptimization_index = safepoint_entry.deoptimization_index();
- ASSERT(deoptimization_index != Safepoint::kNoDeoptimizationIndex);
+ CHECK_NE(deoptimization_index, Safepoint::kNoDeoptimizationIndex);
// Always use the actual stack slots when calculating the fp to sp
// delta adding two for the function and context.
@@ -199,7 +171,7 @@ DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
// Create the GC safe output frame information and register it for GC
// handling.
- ASSERT_LT(jsframe_index, deoptimizer->jsframe_count());
+ CHECK_LT(jsframe_index, deoptimizer->jsframe_count());
// Convert JS frame index into frame index.
int frame_index = deoptimizer->ConvertJSFrameIndexToFrameIndex(jsframe_index);
@@ -251,11 +223,11 @@ DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
void Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
Isolate* isolate) {
- ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == info);
+ CHECK_EQ(isolate->deoptimizer_data()->deoptimized_frame_info_, info);
delete info;
isolate->deoptimizer_data()->deoptimized_frame_info_ = NULL;
}
-#endif
+
void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
int count,
@@ -269,7 +241,7 @@ void Deoptimizer::VisitAllOptimizedFunctionsForContext(
Context* context, OptimizedFunctionVisitor* visitor) {
DisallowHeapAllocation no_allocation;
- ASSERT(context->IsNativeContext());
+ CHECK(context->IsNativeContext());
visitor->EnterContext(context);
@@ -292,13 +264,13 @@ void Deoptimizer::VisitAllOptimizedFunctionsForContext(
context->SetOptimizedFunctionsListHead(next);
}
// The visitor should not alter the link directly.
- ASSERT(function->next_function_link() == next);
+ CHECK_EQ(function->next_function_link(), next);
// Set the next function link to undefined to indicate it is no longer
// in the optimized functions list.
function->set_next_function_link(context->GetHeap()->undefined_value());
} else {
// The visitor should not alter the link directly.
- ASSERT(function->next_function_link() == next);
+ CHECK_EQ(function->next_function_link(), next);
// preserve this element.
prev = function;
}
@@ -400,7 +372,7 @@ void Deoptimizer::DeoptimizeMarkedCodeForContext(Context* context) {
Object* element = context->OptimizedCodeListHead();
while (!element->IsUndefined()) {
Code* code = Code::cast(element);
- ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
+ CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
Object* next = code->next_code_link();
if (code->marked_for_deoptimization()) {
// Put the code into the list for later patching.
@@ -488,7 +460,7 @@ void Deoptimizer::DeoptimizeGlobalObject(JSObject* object) {
}
if (object->IsJSGlobalProxy()) {
Object* proto = object->GetPrototype();
- ASSERT(proto->IsJSGlobalObject());
+ CHECK(proto->IsJSGlobalObject());
Context* native_context = GlobalObject::cast(proto)->native_context();
MarkAllCodeForContext(native_context);
DeoptimizeMarkedCodeForContext(native_context);
@@ -504,7 +476,7 @@ void Deoptimizer::MarkAllCodeForContext(Context* context) {
Object* element = context->OptimizedCodeListHead();
while (!element->IsUndefined()) {
Code* code = Code::cast(element);
- ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
+ CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
code->set_marked_for_deoptimization(true);
element = code->next_code_link();
}
@@ -539,7 +511,7 @@ bool Deoptimizer::TraceEnabledFor(BailoutType deopt_type,
? FLAG_trace_stub_failures
: FLAG_trace_deopt;
}
- UNREACHABLE();
+ FATAL("Unsupported deopt type");
return false;
}
@@ -551,7 +523,7 @@ const char* Deoptimizer::MessageFor(BailoutType type) {
case LAZY: return "lazy";
case DEBUGGER: return "debugger";
}
- UNREACHABLE();
+ FATAL("Unsupported deopt type");
return NULL;
}
@@ -641,7 +613,7 @@ Code* Deoptimizer::FindOptimizedCode(JSFunction* function,
ASSERT(optimized_code->contains(from_));
return optimized_code;
}
- UNREACHABLE();
+ FATAL("Could not find code for optimized function");
return NULL;
}
@@ -684,15 +656,15 @@ Address Deoptimizer::GetDeoptimizationEntry(Isolate* isolate,
int id,
BailoutType type,
GetEntryMode mode) {
- ASSERT(id >= 0);
+ CHECK_GE(id, 0);
if (id >= kMaxNumberOfEntries) return NULL;
if (mode == ENSURE_ENTRY_CODE) {
EnsureCodeForDeoptimizationEntry(isolate, type, id);
} else {
- ASSERT(mode == CALCULATE_ENTRY_ADDRESS);
+ CHECK_EQ(mode, CALCULATE_ENTRY_ADDRESS);
}
DeoptimizerData* data = isolate->deoptimizer_data();
- ASSERT(type < kBailoutTypesWithCodeEntry);
+ CHECK_LT(type, kBailoutTypesWithCodeEntry);
MemoryChunk* base = data->deopt_entry_code_[type];
return base->area_start() + (id * table_entry_size_);
}
@@ -855,7 +827,7 @@ void Deoptimizer::DoComputeOutputFrames() {
case Translation::LITERAL:
case Translation::ARGUMENTS_OBJECT:
default:
- UNREACHABLE();
+ FATAL("Unsupported translation");
break;
}
}
@@ -894,7 +866,7 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
} else {
int closure_id = iterator->Next();
USE(closure_id);
- ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
+ CHECK_EQ(Translation::kSelfLiteralId, closure_id);
function = function_;
}
unsigned height = iterator->Next();
@@ -919,8 +891,8 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
bool is_bottommost = (0 == frame_index);
bool is_topmost = (output_count_ - 1 == frame_index);
- ASSERT(frame_index >= 0 && frame_index < output_count_);
- ASSERT(output_[frame_index] == NULL);
+ CHECK(frame_index >= 0 && frame_index < output_count_);
+ CHECK_EQ(output_[frame_index], NULL);
output_[frame_index] = output_frame;
// The top address for the bottommost output frame can be computed from
@@ -1064,7 +1036,7 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
output_offset -= kPointerSize;
DoTranslateCommand(iterator, frame_index, output_offset);
}
- ASSERT(0 == output_offset);
+ CHECK_EQ(0, output_offset);
// Compute this frame's PC, state, and continuation.
Code* non_optimized_code = function->shared()->code();
@@ -1101,7 +1073,7 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
} else if (bailout_type_ == SOFT) {
continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
} else {
- ASSERT(bailout_type_ == EAGER);
+ CHECK_EQ(bailout_type_, EAGER);
}
output_frame->SetContinuation(
reinterpret_cast<intptr_t>(continuation->entry()));
@@ -1128,8 +1100,8 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR);
// Arguments adaptor can not be topmost or bottommost.
- ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
- ASSERT(output_[frame_index] == NULL);
+ CHECK(frame_index > 0 && frame_index < output_count_ - 1);
+ CHECK(output_[frame_index] == NULL);
output_[frame_index] = output_frame;
// The top address of the frame is computed from the previous
@@ -1275,7 +1247,7 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
// receiver parameter through the translation. It might be encoding
// a captured object, patch the slot address for a captured object.
if (i == 0 && deferred_objects_.length() > deferred_object_index) {
- ASSERT(!deferred_objects_[deferred_object_index].is_arguments());
+ CHECK(!deferred_objects_[deferred_object_index].is_arguments());
deferred_objects_[deferred_object_index].patch_slot_address(top_address);
}
}
@@ -1386,7 +1358,7 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
top_address + output_offset, output_offset, value);
}
- ASSERT(0 == output_offset);
+ CHECK_EQ(0, output_offset);
intptr_t pc = reinterpret_cast<intptr_t>(
construct_stub->instruction_start() +
@@ -1432,8 +1404,8 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
output_frame->SetFrameType(StackFrame::INTERNAL);
// A frame for an accessor stub can not be the topmost or bottommost one.
- ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
- ASSERT(output_[frame_index] == NULL);
+ CHECK(frame_index > 0 && frame_index < output_count_ - 1);
+ CHECK_EQ(output_[frame_index], NULL);
output_[frame_index] = output_frame;
// The top address of the frame is computed from the previous frame's top and
@@ -1517,9 +1489,7 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
}
// Skip receiver.
- Translation::Opcode opcode =
- static_cast<Translation::Opcode>(iterator->Next());
- iterator->Skip(Translation::NumberOfOperandsFor(opcode));
+ DoTranslateObjectAndSkip(iterator);
if (is_setter_stub_frame) {
// The implicit return value was part of the artificial setter stub
@@ -1528,7 +1498,7 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
DoTranslateCommand(iterator, frame_index, output_offset);
}
- ASSERT(0 == output_offset);
+ CHECK_EQ(output_offset, 0);
Smi* offset = is_setter_stub_frame ?
isolate_->heap()->setter_stub_deopt_pc_offset() :
@@ -1578,8 +1548,8 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
// reg = JSFunction context
//
- ASSERT(compiled_code_->is_crankshafted() &&
- compiled_code_->kind() != Code::OPTIMIZED_FUNCTION);
+ CHECK(compiled_code_->is_crankshafted() &&
+ compiled_code_->kind() != Code::OPTIMIZED_FUNCTION);
int major_key = compiled_code_->major_key();
CodeStubInterfaceDescriptor* descriptor =
isolate_->code_stub_interface_descriptor(major_key);
@@ -1588,7 +1558,7 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
// and the standard stack frame slots. Include space for an argument
// object to the callee and optionally the space to pass the argument
// object to the stub failure handler.
- ASSERT(descriptor->register_param_count_ >= 0);
+ CHECK_GE(descriptor->register_param_count_, 0);
int height_in_bytes = kPointerSize * descriptor->register_param_count_ +
sizeof(Arguments) + kPointerSize;
int fixed_frame_size = StandardFrameConstants::kFixedFrameSize;
@@ -1605,7 +1575,7 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
FrameDescription* output_frame =
new(output_frame_size) FrameDescription(output_frame_size, NULL);
output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE);
- ASSERT(frame_index == 0);
+ CHECK_EQ(frame_index, 0);
output_[frame_index] = output_frame;
// The top address for the output frame can be computed from the input
@@ -1663,7 +1633,7 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
output_frame->SetRegister(context_reg.code(), value);
output_frame_offset -= kPointerSize;
output_frame->SetFrameSlot(output_frame_offset, value);
- ASSERT(reinterpret_cast<Object*>(value)->IsContext());
+ CHECK(reinterpret_cast<Object*>(value)->IsContext());
if (trace_scope_ != NULL) {
PrintF(trace_scope_->file(),
" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
@@ -1741,10 +1711,10 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
}
}
- ASSERT(0 == output_frame_offset);
+ CHECK_EQ(output_frame_offset, 0);
if (!arg_count_known) {
- ASSERT(arguments_length_offset >= 0);
+ CHECK_GE(arguments_length_offset, 0);
// We know it's a smi because 1) the code stub guarantees the stack
// parameter count is in smi range, and 2) the DoTranslateCommand in the
// parameter loop above translated that to a tagged value.
@@ -1780,8 +1750,8 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
// Compute this frame's PC, state, and continuation.
Code* trampoline = NULL;
StubFunctionMode function_mode = descriptor->function_mode_;
- StubFailureTrampolineStub(function_mode).FindCodeInCache(&trampoline,
- isolate_);
+ StubFailureTrampolineStub(isolate_,
+ function_mode).FindCodeInCache(&trampoline);
ASSERT(trampoline != NULL);
output_frame->SetPc(reinterpret_cast<intptr_t>(
trampoline->instruction_start()));
@@ -1828,7 +1798,7 @@ Handle<Object> Deoptimizer::MaterializeNextHeapObject() {
Handle<JSObject> arguments =
isolate_->factory()->NewArgumentsObject(function, length);
Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length);
- ASSERT(array->length() == length);
+ ASSERT_EQ(array->length(), length);
arguments->set_elements(*array);
materialized_objects_->Add(arguments);
for (int i = 0; i < length; ++i) {
@@ -1840,7 +1810,7 @@ Handle<Object> Deoptimizer::MaterializeNextHeapObject() {
// We also need to make sure that the representation of all fields
// in the given object are general enough to hold a tagged value.
Handle<Map> map = Map::GeneralizeAllFieldRepresentations(
- Handle<Map>::cast(MaterializeNextValue()), Representation::Tagged());
+ Handle<Map>::cast(MaterializeNextValue()));
switch (map->instance_type()) {
case HEAP_NUMBER_TYPE: {
// Reuse the HeapNumber value directly as it is already properly
@@ -1894,7 +1864,7 @@ Handle<Object> Deoptimizer::MaterializeNextHeapObject() {
default:
PrintF(stderr,
"[couldn't handle instance type %d]\n", map->instance_type());
- UNREACHABLE();
+ FATAL("Unsupported instance type");
}
}
@@ -1988,7 +1958,9 @@ void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
// materialize a new instance of the object if necessary. Store
// the materialized object into the frame slot.
Handle<Object> object = MaterializeNextHeapObject();
- Memory::Object_at(descriptor.slot_address()) = *object;
+ if (descriptor.slot_address() != NULL) {
+ Memory::Object_at(descriptor.slot_address()) = *object;
+ }
if (trace_scope_ != NULL) {
if (descriptor.is_arguments()) {
PrintF(trace_scope_->file(),
@@ -2007,8 +1979,8 @@ void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
}
}
- ASSERT(materialization_object_index_ == materialized_objects_->length());
- ASSERT(materialization_value_index_ == materialized_values_->length());
+ CHECK_EQ(materialization_object_index_, materialized_objects_->length());
+ CHECK_EQ(materialization_value_index_, materialized_values_->length());
}
if (prev_materialized_count_ > 0) {
@@ -2017,14 +1989,13 @@ void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
Address parameters_top,
uint32_t parameters_size,
Address expressions_top,
uint32_t expressions_size,
DeoptimizedFrameInfo* info) {
- ASSERT_EQ(DEBUGGER, bailout_type_);
+ CHECK_EQ(DEBUGGER, bailout_type_);
Address parameters_bottom = parameters_top + parameters_size;
Address expressions_bottom = expressions_top + expressions_size;
for (int i = 0; i < deferred_heap_numbers_.length(); i++) {
@@ -2070,7 +2041,6 @@ void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
}
}
}
-#endif
static const char* TraceValueType(bool is_smi) {
@@ -2082,6 +2052,73 @@ static const char* TraceValueType(bool is_smi) {
}
+void Deoptimizer::DoTranslateObjectAndSkip(TranslationIterator* iterator) {
+ Translation::Opcode opcode =
+ static_cast<Translation::Opcode>(iterator->Next());
+
+ switch (opcode) {
+ case Translation::BEGIN:
+ case Translation::JS_FRAME:
+ case Translation::ARGUMENTS_ADAPTOR_FRAME:
+ case Translation::CONSTRUCT_STUB_FRAME:
+ case Translation::GETTER_STUB_FRAME:
+ case Translation::SETTER_STUB_FRAME:
+ case Translation::COMPILED_STUB_FRAME: {
+ FATAL("Unexpected frame start translation opcode");
+ return;
+ }
+
+ case Translation::REGISTER:
+ case Translation::INT32_REGISTER:
+ case Translation::UINT32_REGISTER:
+ case Translation::DOUBLE_REGISTER:
+ case Translation::STACK_SLOT:
+ case Translation::INT32_STACK_SLOT:
+ case Translation::UINT32_STACK_SLOT:
+ case Translation::DOUBLE_STACK_SLOT:
+ case Translation::LITERAL: {
+ // The value is not part of any materialized object, so we can ignore it.
+ iterator->Skip(Translation::NumberOfOperandsFor(opcode));
+ return;
+ }
+
+ case Translation::DUPLICATED_OBJECT: {
+ int object_index = iterator->Next();
+ if (trace_scope_ != NULL) {
+ PrintF(trace_scope_->file(), " skipping object ");
+ PrintF(trace_scope_->file(),
+ " ; duplicate of object #%d\n", object_index);
+ }
+ AddObjectDuplication(0, object_index);
+ return;
+ }
+
+ case Translation::ARGUMENTS_OBJECT:
+ case Translation::CAPTURED_OBJECT: {
+ int length = iterator->Next();
+ bool is_args = opcode == Translation::ARGUMENTS_OBJECT;
+ if (trace_scope_ != NULL) {
+ PrintF(trace_scope_->file(), " skipping object ");
+ PrintF(trace_scope_->file(),
+ " ; object (length = %d, is_args = %d)\n", length, is_args);
+ }
+
+ AddObjectStart(0, length, is_args);
+
+ // We save the object values on the side and materialize the actual
+ // object after the deoptimized frame is built.
+ int object_index = deferred_objects_.length() - 1;
+ for (int i = 0; i < length; i++) {
+ DoTranslateObject(iterator, object_index, i);
+ }
+ return;
+ }
+ }
+
+ FATAL("Unexpected translation opcode");
+}
+
+
void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
int object_index,
int field_index) {
@@ -2099,7 +2136,7 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
case Translation::GETTER_STUB_FRAME:
case Translation::SETTER_STUB_FRAME:
case Translation::COMPILED_STUB_FRAME:
- UNREACHABLE();
+ FATAL("Unexpected frame start translation opcode");
return;
case Translation::REGISTER: {
@@ -2339,6 +2376,8 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
return;
}
}
+
+ FATAL("Unexpected translation opcode");
}
@@ -2360,7 +2399,7 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
case Translation::GETTER_STUB_FRAME:
case Translation::SETTER_STUB_FRAME:
case Translation::COMPILED_STUB_FRAME:
- UNREACHABLE();
+ FATAL("Unexpected translation opcode");
return;
case Translation::REGISTER: {
@@ -2632,13 +2671,11 @@ unsigned Deoptimizer::ComputeInputFrameSize() const {
// function into account so we have to avoid double counting them.
unsigned result = fixed_size + fp_to_sp_delta_ -
StandardFrameConstants::kFixedFrameSizeFromFp;
-#ifdef DEBUG
if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) {
unsigned stack_slots = compiled_code_->stack_slots();
unsigned outgoing_size = ComputeOutgoingArgumentSize();
- ASSERT(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size);
+ CHECK(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size);
}
-#endif
return result;
}
@@ -2655,7 +2692,7 @@ unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const {
// The incoming arguments is the values for formal parameters and
// the receiver. Every slot contains a pointer.
if (function->IsSmi()) {
- ASSERT(Smi::cast(function) == Smi::FromInt(StackFrame::STUB));
+ CHECK_EQ(Smi::cast(function), Smi::FromInt(StackFrame::STUB));
return 0;
}
unsigned arguments = function->shared()->formal_parameter_count() + 1;
@@ -2720,13 +2757,13 @@ void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
// cause us to emit relocation information for the external
// references. This is fine because the deoptimizer's code section
// isn't meant to be serialized at all.
- ASSERT(type == EAGER || type == SOFT || type == LAZY);
+ CHECK(type == EAGER || type == SOFT || type == LAZY);
DeoptimizerData* data = isolate->deoptimizer_data();
int entry_count = data->deopt_entry_code_entries_[type];
if (max_entry_id < entry_count) return;
entry_count = Max(entry_count, Deoptimizer::kMinNumberOfEntries);
while (max_entry_id >= entry_count) entry_count *= 2;
- ASSERT(entry_count <= Deoptimizer::kMaxNumberOfEntries);
+ CHECK(entry_count <= Deoptimizer::kMaxNumberOfEntries);
MacroAssembler masm(isolate, NULL, 16 * KB);
masm.set_emit_debug_code(false);
@@ -2736,8 +2773,8 @@ void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
ASSERT(!RelocInfo::RequiresRelocation(desc));
MemoryChunk* chunk = data->deopt_entry_code_[type];
- ASSERT(static_cast<int>(Deoptimizer::GetMaxDeoptTableSize()) >=
- desc.instr_size);
+ CHECK(static_cast<int>(Deoptimizer::GetMaxDeoptTableSize()) >=
+ desc.instr_size);
chunk->CommitArea(desc.instr_size);
CopyBytes(chunk->area_start(), desc.buffer,
static_cast<size_t>(desc.instr_size));
@@ -2804,15 +2841,15 @@ int FrameDescription::ComputeParametersCount() {
case StackFrame::STUB:
return -1; // Minus receiver.
default:
- UNREACHABLE();
+ FATAL("Unexpected stack frame type");
return 0;
}
}
Object* FrameDescription::GetParameter(int index) {
- ASSERT(index >= 0);
- ASSERT(index < ComputeParametersCount());
+ CHECK_GE(index, 0);
+ CHECK_LT(index, ComputeParametersCount());
// The slot indexes for incoming arguments are negative.
unsigned offset = GetOffsetFromSlotIndex(index - ComputeParametersCount());
return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
@@ -2820,7 +2857,7 @@ Object* FrameDescription::GetParameter(int index) {
unsigned FrameDescription::GetExpressionCount() {
- ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_);
+ CHECK_EQ(StackFrame::JAVA_SCRIPT, type_);
unsigned size = GetFrameSize() - ComputeFixedSize();
return size / kPointerSize;
}
@@ -3022,7 +3059,7 @@ int Translation::NumberOfOperandsFor(Opcode opcode) {
case JS_FRAME:
return 3;
}
- UNREACHABLE();
+ FATAL("Unexpected translation type");
return -1;
}
@@ -3132,14 +3169,13 @@ SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame,
TranslationIterator it(data->TranslationByteArray(),
data->TranslationIndex(deopt_index)->value());
Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
- ASSERT(opcode == Translation::BEGIN);
+ CHECK_EQ(opcode, Translation::BEGIN);
it.Next(); // Drop frame count.
stack_frame_id_ = frame->fp();
int jsframe_count = it.Next();
- USE(jsframe_count);
- ASSERT(jsframe_count > inlined_jsframe_index);
+ CHECK_GT(jsframe_count, inlined_jsframe_index);
int jsframes_to_skip = inlined_jsframe_index;
int number_of_slots = -1; // Number of slots inside our frame (yet unknown)
bool should_deopt = false;
@@ -3148,7 +3184,7 @@ SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame,
bool processed = false;
if (opcode == Translation::ARGUMENTS_ADAPTOR_FRAME) {
if (jsframes_to_skip == 0) {
- ASSERT(Translation::NumberOfOperandsFor(opcode) == 2);
+ CHECK_EQ(Translation::NumberOfOperandsFor(opcode), 2);
it.Skip(1); // literal id
int height = it.Next();
@@ -3195,7 +3231,7 @@ SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame,
// the nested slots of captured objects
number_of_slots--;
SlotRef& slot = slot_refs_.last();
- ASSERT(slot.Representation() != SlotRef::ARGUMENTS_OBJECT);
+ CHECK_NE(slot.Representation(), SlotRef::ARGUMENTS_OBJECT);
number_of_slots += slot.GetChildrenCount();
if (slot.Representation() == SlotRef::DEFERRED_OBJECT ||
slot.Representation() == SlotRef::DUPLICATE_OBJECT) {
@@ -3269,7 +3305,7 @@ void SlotRefValueBuilder::Prepare(Isolate* isolate) {
while (current_slot_ < first_slot_index_) {
GetNext(isolate, 0);
}
- ASSERT(current_slot_ == first_slot_index_);
+ CHECK_EQ(current_slot_, first_slot_index_);
}
@@ -3331,8 +3367,8 @@ Handle<Object> SlotRefValueBuilder::GetNext(Isolate* isolate, int lvl) {
}
case SlotRef::DEFERRED_OBJECT: {
int length = slot.GetChildrenCount();
- ASSERT(slot_refs_[current_slot_].Representation() == SlotRef::LITERAL ||
- slot_refs_[current_slot_].Representation() == SlotRef::TAGGED);
+ CHECK(slot_refs_[current_slot_].Representation() == SlotRef::LITERAL ||
+ slot_refs_[current_slot_].Representation() == SlotRef::TAGGED);
int object_index = materialized_objects_.length();
if (object_index < prev_materialized_count_) {
@@ -3341,7 +3377,7 @@ Handle<Object> SlotRefValueBuilder::GetNext(Isolate* isolate, int lvl) {
Handle<Object> map_object = slot_refs_[current_slot_].GetValue(isolate);
Handle<Map> map = Map::GeneralizeAllFieldRepresentations(
- Handle<Map>::cast(map_object), Representation::Tagged());
+ Handle<Map>::cast(map_object));
current_slot_++;
// TODO(jarin) this should be unified with the code in
// Deoptimizer::MaterializeNextHeapObject()
@@ -3393,6 +3429,7 @@ Handle<Object> SlotRefValueBuilder::GetNext(Isolate* isolate, int lvl) {
break;
}
UNREACHABLE();
+ break;
}
case SlotRef::DUPLICATE_OBJECT: {
@@ -3413,7 +3450,7 @@ Handle<Object> SlotRefValueBuilder::GetNext(Isolate* isolate, int lvl) {
void SlotRefValueBuilder::Finish(Isolate* isolate) {
// We should have processed all the slots
- ASSERT(slot_refs_.length() == current_slot_);
+ CHECK_EQ(slot_refs_.length(), current_slot_);
if (materialized_objects_.length() > prev_materialized_count_) {
// We have materialized some new objects, so we have to store them
@@ -3434,7 +3471,7 @@ Handle<FixedArray> MaterializedObjectStore::Get(Address fp) {
return Handle<FixedArray>::null();
}
Handle<FixedArray> array = GetStackEntries();
- ASSERT(array->length() > index);
+ CHECK_GT(array->length(), index);
return Handle<FixedArray>::cast(Handle<Object>(array->get(index),
isolate()));
}
@@ -3455,11 +3492,11 @@ void MaterializedObjectStore::Set(Address fp,
void MaterializedObjectStore::Remove(Address fp) {
int index = StackIdToIndex(fp);
- ASSERT(index >= 0);
+ CHECK_GE(index, 0);
frame_fps_.Remove(index);
Handle<FixedArray> array = GetStackEntries();
- ASSERT(array->length() > index);
+ CHECK_LT(index, array->length());
for (int i = index; i < frame_fps_.length(); i++) {
array->set(i, array->get(i + 1));
}
@@ -3505,7 +3542,6 @@ Handle<FixedArray> MaterializedObjectStore::EnsureStackEntries(int length) {
return new_array;
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
DeoptimizedFrameInfo::DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
int frame_index,
@@ -3527,7 +3563,7 @@ DeoptimizedFrameInfo::DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
if (has_arguments_adaptor) {
output_frame = deoptimizer->output_[frame_index - 1];
- ASSERT(output_frame->GetFrameType() == StackFrame::ARGUMENTS_ADAPTOR);
+ CHECK_EQ(output_frame->GetFrameType(), StackFrame::ARGUMENTS_ADAPTOR);
}
parameters_count_ = output_frame->ComputeParametersCount();
@@ -3550,6 +3586,4 @@ void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) {
v->VisitPointers(expression_stack_, expression_stack_ + expression_count_);
}
-#endif // ENABLE_DEBUGGER_SUPPORT
-
} } // namespace v8::internal
diff --git a/deps/v8/src/deoptimizer.h b/deps/v8/src/deoptimizer.h
index a36362fc93..373f888ae3 100644
--- a/deps/v8/src/deoptimizer.h
+++ b/deps/v8/src/deoptimizer.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_DEOPTIMIZER_H_
#define V8_DEOPTIMIZER_H_
@@ -169,7 +146,6 @@ class Deoptimizer : public Malloced {
Isolate* isolate);
static Deoptimizer* Grab(Isolate* isolate);
-#ifdef ENABLE_DEBUGGER_SUPPORT
// The returned object with information on the optimized frame needs to be
// freed before another one can be generated.
static DeoptimizedFrameInfo* DebuggerInspectableFrame(JavaScriptFrame* frame,
@@ -177,7 +153,6 @@ class Deoptimizer : public Malloced {
Isolate* isolate);
static void DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
Isolate* isolate);
-#endif
// Makes sure that there is enough room in the relocation
// information of a code object to perform lazy deoptimization
@@ -212,14 +187,13 @@ class Deoptimizer : public Malloced {
~Deoptimizer();
void MaterializeHeapObjects(JavaScriptFrameIterator* it);
-#ifdef ENABLE_DEBUGGER_SUPPORT
+
void MaterializeHeapNumbersForDebuggerInspectableFrame(
Address parameters_top,
uint32_t parameters_size,
Address expressions_top,
uint32_t expressions_size,
DeoptimizedFrameInfo* info);
-#endif
static void ComputeOutputFrames(Deoptimizer* deoptimizer);
@@ -329,14 +303,21 @@ class Deoptimizer : public Malloced {
void DoComputeCompiledStubFrame(TranslationIterator* iterator,
int frame_index);
+ // Translate object, store the result into an auxiliary array
+ // (deferred_objects_tagged_values_).
void DoTranslateObject(TranslationIterator* iterator,
int object_index,
int field_index);
+ // Translate value, store the result into the given frame slot.
void DoTranslateCommand(TranslationIterator* iterator,
int frame_index,
unsigned output_offset);
+ // Translate object, do not store the result anywhere (but do update
+ // the deferred materialization array).
+ void DoTranslateObjectAndSkip(TranslationIterator* iterator);
+
unsigned ComputeInputFrameSize() const;
unsigned ComputeFixedSize(JSFunction* function) const;
@@ -644,18 +625,14 @@ class DeoptimizerData {
explicit DeoptimizerData(MemoryAllocator* allocator);
~DeoptimizerData();
-#ifdef ENABLE_DEBUGGER_SUPPORT
void Iterate(ObjectVisitor* v);
-#endif
private:
MemoryAllocator* allocator_;
int deopt_entry_code_entries_[Deoptimizer::kBailoutTypesWithCodeEntry];
MemoryChunk* deopt_entry_code_[Deoptimizer::kBailoutTypesWithCodeEntry];
-#ifdef ENABLE_DEBUGGER_SUPPORT
DeoptimizedFrameInfo* deoptimized_frame_info_;
-#endif
Deoptimizer* current_;
@@ -919,7 +896,6 @@ class MaterializedObjectStore {
};
-#ifdef ENABLE_DEBUGGER_SUPPORT
// Class used to represent an unoptimized frame when the debugger
// needs to inspect a frame that is part of an optimized frame. The
// internally used FrameDescription objects are not GC safe so for use
@@ -993,7 +969,6 @@ class DeoptimizedFrameInfo : public Malloced {
friend class Deoptimizer;
};
-#endif
} } // namespace v8::internal
diff --git a/deps/v8/src/disasm.h b/deps/v8/src/disasm.h
index f7f2d41202..89b7fc2615 100644
--- a/deps/v8/src/disasm.h
+++ b/deps/v8/src/disasm.h
@@ -1,29 +1,6 @@
// Copyright 2007-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_DISASM_H_
#define V8_DISASM_H_
diff --git a/deps/v8/src/disassembler.cc b/deps/v8/src/disassembler.cc
index 2af64228c6..754d5a77a5 100644
--- a/deps/v8/src/disassembler.cc
+++ b/deps/v8/src/disassembler.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/disassembler.h b/deps/v8/src/disassembler.h
index 8789150036..f5f596efc9 100644
--- a/deps/v8/src/disassembler.h
+++ b/deps/v8/src/disassembler.h
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_DISASSEMBLER_H_
#define V8_DISASSEMBLER_H_
diff --git a/deps/v8/src/diy-fp.cc b/deps/v8/src/diy-fp.cc
index 4913877708..51f75abb73 100644
--- a/deps/v8/src/diy-fp.cc
+++ b/deps/v8/src/diy-fp.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "../include/v8stdint.h"
#include "globals.h"
diff --git a/deps/v8/src/diy-fp.h b/deps/v8/src/diy-fp.h
index 26ff1a20bf..f8f2673c41 100644
--- a/deps/v8/src/diy-fp.h
+++ b/deps/v8/src/diy-fp.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_DIY_FP_H_
#define V8_DIY_FP_H_
diff --git a/deps/v8/src/double.h b/deps/v8/src/double.h
index fcf6906af7..9fb7f843ad 100644
--- a/deps/v8/src/double.h
+++ b/deps/v8/src/double.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_DOUBLE_H_
#define V8_DOUBLE_H_
diff --git a/deps/v8/src/dtoa.cc b/deps/v8/src/dtoa.cc
index bda67205c7..42a95ed96e 100644
--- a/deps/v8/src/dtoa.cc
+++ b/deps/v8/src/dtoa.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <cmath>
diff --git a/deps/v8/src/dtoa.h b/deps/v8/src/dtoa.h
index 948a079191..dd88688d08 100644
--- a/deps/v8/src/dtoa.h
+++ b/deps/v8/src/dtoa.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_DTOA_H_
#define V8_DTOA_H_
diff --git a/deps/v8/src/effects.h b/deps/v8/src/effects.h
index 5d980f54ed..9360fda045 100644
--- a/deps/v8/src/effects.h
+++ b/deps/v8/src/effects.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_EFFECTS_H_
#define V8_EFFECTS_H_
diff --git a/deps/v8/src/elements-kind.cc b/deps/v8/src/elements-kind.cc
index ff458e0ea1..adab39679d 100644
--- a/deps/v8/src/elements-kind.cc
+++ b/deps/v8/src/elements-kind.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "elements-kind.h"
@@ -172,28 +149,55 @@ ElementsKind GetNextMoreGeneralFastElementsKind(ElementsKind elements_kind,
}
+static bool IsTypedArrayElementsKind(ElementsKind elements_kind) {
+ return IsFixedTypedArrayElementsKind(elements_kind) ||
+ IsExternalArrayElementsKind(elements_kind);
+}
+
+
+static inline bool IsFastTransitionTarget(ElementsKind elements_kind) {
+ return IsFastElementsKind(elements_kind) ||
+ elements_kind == DICTIONARY_ELEMENTS;
+}
+
bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
ElementsKind to_kind) {
- switch (from_kind) {
- case FAST_SMI_ELEMENTS:
- return to_kind != FAST_SMI_ELEMENTS;
- case FAST_HOLEY_SMI_ELEMENTS:
- return to_kind != FAST_SMI_ELEMENTS &&
- to_kind != FAST_HOLEY_SMI_ELEMENTS;
- case FAST_DOUBLE_ELEMENTS:
- return to_kind != FAST_SMI_ELEMENTS &&
- to_kind != FAST_HOLEY_SMI_ELEMENTS &&
- to_kind != FAST_DOUBLE_ELEMENTS;
- case FAST_HOLEY_DOUBLE_ELEMENTS:
- return to_kind == FAST_ELEMENTS ||
- to_kind == FAST_HOLEY_ELEMENTS;
- case FAST_ELEMENTS:
- return to_kind == FAST_HOLEY_ELEMENTS;
- case FAST_HOLEY_ELEMENTS:
- return false;
- default:
- return false;
+ if (IsTypedArrayElementsKind(from_kind) ||
+ IsTypedArrayElementsKind(to_kind)) {
+ switch (from_kind) {
+#define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+ case TYPE##_ELEMENTS: \
+ return to_kind == EXTERNAL_##TYPE##_ELEMENTS;
+
+ TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE);
+#undef FIXED_TYPED_ARRAY_CASE
+ default:
+ return false;
+ }
+ }
+ if (IsFastElementsKind(from_kind) && IsFastTransitionTarget(to_kind)) {
+ switch (from_kind) {
+ case FAST_SMI_ELEMENTS:
+ return to_kind != FAST_SMI_ELEMENTS;
+ case FAST_HOLEY_SMI_ELEMENTS:
+ return to_kind != FAST_SMI_ELEMENTS &&
+ to_kind != FAST_HOLEY_SMI_ELEMENTS;
+ case FAST_DOUBLE_ELEMENTS:
+ return to_kind != FAST_SMI_ELEMENTS &&
+ to_kind != FAST_HOLEY_SMI_ELEMENTS &&
+ to_kind != FAST_DOUBLE_ELEMENTS;
+ case FAST_HOLEY_DOUBLE_ELEMENTS:
+ return to_kind == FAST_ELEMENTS ||
+ to_kind == FAST_HOLEY_ELEMENTS;
+ case FAST_ELEMENTS:
+ return to_kind == FAST_HOLEY_ELEMENTS;
+ case FAST_HOLEY_ELEMENTS:
+ return false;
+ default:
+ return false;
+ }
}
+ return false;
}
diff --git a/deps/v8/src/elements-kind.h b/deps/v8/src/elements-kind.h
index d2605e8b06..1a550b0a33 100644
--- a/deps/v8/src/elements-kind.h
+++ b/deps/v8/src/elements-kind.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ELEMENTS_KIND_H_
#define V8_ELEMENTS_KIND_H_
diff --git a/deps/v8/src/elements.cc b/deps/v8/src/elements.cc
index 0624a03621..580a7186bd 100644
--- a/deps/v8/src/elements.cc
+++ b/deps/v8/src/elements.cc
@@ -1,37 +1,14 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
#include "arguments.h"
-#include "objects.h"
+#include "conversions.h"
#include "elements.h"
+#include "objects.h"
#include "utils.h"
-#include "v8conversions.h"
// Each concrete ElementsAccessor can handle exactly one ElementsKind,
// several abstract ElementsAccessor classes are used to allow sharing
@@ -146,7 +123,9 @@ ELEMENTS_LIST(ELEMENTS_TRAITS)
ElementsAccessor** ElementsAccessor::elements_accessors_;
-static bool HasKey(FixedArray* array, Object* key) {
+static bool HasKey(Handle<FixedArray> array, Handle<Object> key_handle) {
+ DisallowHeapAllocation no_gc;
+ Object* key = *key_handle;
int len0 = array->length();
for (int i = 0; i < len0; i++) {
Object* element = array->get(i);
@@ -160,11 +139,11 @@ static bool HasKey(FixedArray* array, Object* key) {
}
-static Handle<Object> ThrowArrayLengthRangeError(Isolate* isolate) {
- isolate->Throw(
- *isolate->factory()->NewRangeError("invalid_array_length",
- HandleVector<Object>(NULL, 0)));
- return Handle<Object>();
+MUST_USE_RESULT
+static MaybeHandle<Object> ThrowArrayLengthRangeError(Isolate* isolate) {
+ return isolate->Throw<Object>(
+ isolate->factory()->NewRangeError("invalid_array_length",
+ HandleVector<Object>(NULL, 0)));
}
@@ -302,15 +281,16 @@ static void CopyDoubleToObjectElements(Handle<FixedArrayBase> from_base,
ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
(copy_size + static_cast<int>(from_start)) <= from_base->length());
if (copy_size == 0) return;
+ Isolate* isolate = from_base->GetIsolate();
Handle<FixedDoubleArray> from = Handle<FixedDoubleArray>::cast(from_base);
Handle<FixedArray> to = Handle<FixedArray>::cast(to_base);
for (int i = 0; i < copy_size; ++i) {
- HandleScope scope(from_base->GetIsolate());
+ HandleScope scope(isolate);
if (IsFastSmiElementsKind(to_kind)) {
UNIMPLEMENTED();
} else {
ASSERT(IsFastObjectElementsKind(to_kind));
- Handle<Object> value = from->get_as_handle(i + from_start);
+ Handle<Object> value = FixedDoubleArray::get(from, i + from_start);
to->set(i + to_start, *value, UPDATE_WRITE_BARRIER);
}
}
@@ -517,12 +497,13 @@ static void TraceTopFrame(Isolate* isolate) {
}
-void CheckArrayAbuse(JSObject* obj, const char* op, uint32_t key,
+void CheckArrayAbuse(Handle<JSObject> obj, const char* op, uint32_t key,
bool allow_appending) {
+ DisallowHeapAllocation no_allocation;
Object* raw_length = NULL;
const char* elements_type = "array";
if (obj->IsJSArray()) {
- JSArray* array = JSArray::cast(obj);
+ JSArray* array = JSArray::cast(*obj);
raw_length = array->length();
} else {
raw_length = Smi::FromInt(obj->elements()->length());
@@ -587,19 +568,17 @@ class ElementsAccessorBase : public ElementsAccessor {
return ElementsTraits::Kind;
}
- static void ValidateContents(JSObject* holder, int length) {
+ static void ValidateContents(Handle<JSObject> holder, int length) {
}
- static void ValidateImpl(JSObject* holder) {
- FixedArrayBase* fixed_array_base = holder->elements();
- // When objects are first allocated, its elements are Failures.
- if (fixed_array_base->IsFailure()) return;
+ static void ValidateImpl(Handle<JSObject> holder) {
+ Handle<FixedArrayBase> fixed_array_base(holder->elements());
if (!fixed_array_base->IsHeapObject()) return;
// Arrays that have been shifted in place can't be verified.
if (fixed_array_base->IsFiller()) return;
int length = 0;
if (holder->IsJSArray()) {
- Object* length_obj = JSArray::cast(holder)->length();
+ Object* length_obj = Handle<JSArray>::cast(holder)->length();
if (length_obj->IsSmi()) {
length = Smi::cast(length_obj)->value();
}
@@ -609,51 +588,33 @@ class ElementsAccessorBase : public ElementsAccessor {
ElementsAccessorSubclass::ValidateContents(holder, length);
}
- virtual void Validate(JSObject* holder) V8_FINAL V8_OVERRIDE {
+ virtual void Validate(Handle<JSObject> holder) V8_FINAL V8_OVERRIDE {
+ DisallowHeapAllocation no_gc;
ElementsAccessorSubclass::ValidateImpl(holder);
}
- static bool HasElementImpl(Object* receiver,
- JSObject* holder,
+ static bool HasElementImpl(Handle<Object> receiver,
+ Handle<JSObject> holder,
uint32_t key,
- FixedArrayBase* backing_store) {
+ Handle<FixedArrayBase> backing_store) {
return ElementsAccessorSubclass::GetAttributesImpl(
receiver, holder, key, backing_store) != ABSENT;
}
- virtual bool HasElement(Object* receiver,
- JSObject* holder,
- uint32_t key,
- FixedArrayBase* backing_store) V8_FINAL V8_OVERRIDE {
- if (backing_store == NULL) {
- backing_store = holder->elements();
- }
+ virtual bool HasElement(
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
+ uint32_t key,
+ Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE {
return ElementsAccessorSubclass::HasElementImpl(
receiver, holder, key, backing_store);
}
- // TODO(ishell): Temporary wrapper until handlified.
- MUST_USE_RESULT virtual Handle<Object> Get(
+ MUST_USE_RESULT virtual MaybeHandle<Object> Get(
Handle<Object> receiver,
Handle<JSObject> holder,
uint32_t key,
Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE {
- CALL_HEAP_FUNCTION(holder->GetIsolate(),
- Get(*receiver, *holder, key,
- backing_store.is_null()
- ? NULL : *backing_store),
- Object);
- }
-
- MUST_USE_RESULT virtual MaybeObject* Get(
- Object* receiver,
- JSObject* holder,
- uint32_t key,
- FixedArrayBase* backing_store) V8_FINAL V8_OVERRIDE {
- if (backing_store == NULL) {
- backing_store = holder->elements();
- }
-
if (!IsExternalArrayElementsKind(ElementsTraits::Kind) &&
FLAG_trace_js_array_abuse) {
CheckArrayAbuse(holder, "elements read", key);
@@ -668,90 +629,87 @@ class ElementsAccessorBase : public ElementsAccessor {
receiver, holder, key, backing_store);
}
- MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
- JSObject* obj,
- uint32_t key,
- FixedArrayBase* backing_store) {
- return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store))
- ? BackingStore::cast(backing_store)->get(key)
- : backing_store->GetHeap()->the_hole_value();
+ MUST_USE_RESULT static MaybeHandle<Object> GetImpl(
+ Handle<Object> receiver,
+ Handle<JSObject> obj,
+ uint32_t key,
+ Handle<FixedArrayBase> backing_store) {
+ if (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) {
+ return BackingStore::get(Handle<BackingStore>::cast(backing_store), key);
+ } else {
+ return backing_store->GetIsolate()->factory()->the_hole_value();
+ }
}
MUST_USE_RESULT virtual PropertyAttributes GetAttributes(
- Object* receiver,
- JSObject* holder,
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
uint32_t key,
- FixedArrayBase* backing_store) V8_FINAL V8_OVERRIDE {
- if (backing_store == NULL) {
- backing_store = holder->elements();
- }
+ Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE {
return ElementsAccessorSubclass::GetAttributesImpl(
receiver, holder, key, backing_store);
}
MUST_USE_RESULT static PropertyAttributes GetAttributesImpl(
- Object* receiver,
- JSObject* obj,
+ Handle<Object> receiver,
+ Handle<JSObject> obj,
uint32_t key,
- FixedArrayBase* backing_store) {
+ Handle<FixedArrayBase> backing_store) {
if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) {
return ABSENT;
}
- return BackingStore::cast(backing_store)->is_the_hole(key) ? ABSENT : NONE;
+ return
+ Handle<BackingStore>::cast(backing_store)->is_the_hole(key)
+ ? ABSENT : NONE;
}
MUST_USE_RESULT virtual PropertyType GetType(
- Object* receiver,
- JSObject* holder,
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
uint32_t key,
- FixedArrayBase* backing_store) V8_FINAL V8_OVERRIDE {
- if (backing_store == NULL) {
- backing_store = holder->elements();
- }
+ Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE {
return ElementsAccessorSubclass::GetTypeImpl(
receiver, holder, key, backing_store);
}
MUST_USE_RESULT static PropertyType GetTypeImpl(
- Object* receiver,
- JSObject* obj,
- uint32_t key,
- FixedArrayBase* backing_store) {
+ Handle<Object> receiver,
+ Handle<JSObject> obj,
+ uint32_t key,
+ Handle<FixedArrayBase> backing_store) {
if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) {
return NONEXISTENT;
}
- return BackingStore::cast(backing_store)->is_the_hole(key)
- ? NONEXISTENT : FIELD;
+ return
+ Handle<BackingStore>::cast(backing_store)->is_the_hole(key)
+ ? NONEXISTENT : FIELD;
}
- MUST_USE_RESULT virtual AccessorPair* GetAccessorPair(
- Object* receiver,
- JSObject* holder,
+ MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair(
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
uint32_t key,
- FixedArrayBase* backing_store) V8_FINAL V8_OVERRIDE {
- if (backing_store == NULL) {
- backing_store = holder->elements();
- }
+ Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE {
return ElementsAccessorSubclass::GetAccessorPairImpl(
receiver, holder, key, backing_store);
}
- MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl(
- Object* receiver,
- JSObject* obj,
- uint32_t key,
- FixedArrayBase* backing_store) {
- return NULL;
+ MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl(
+ Handle<Object> receiver,
+ Handle<JSObject> obj,
+ uint32_t key,
+ Handle<FixedArrayBase> backing_store) {
+ return MaybeHandle<AccessorPair>();
}
- MUST_USE_RESULT virtual Handle<Object> SetLength(
+ MUST_USE_RESULT virtual MaybeHandle<Object> SetLength(
Handle<JSArray> array,
Handle<Object> length) V8_FINAL V8_OVERRIDE {
return ElementsAccessorSubclass::SetLengthImpl(
array, length, handle(array->elements()));
}
- MUST_USE_RESULT static Handle<Object> SetLengthImpl(
+ MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl(
Handle<JSObject> obj,
Handle<Object> length,
Handle<FixedArrayBase> backing_store);
@@ -771,7 +729,7 @@ class ElementsAccessorBase : public ElementsAccessor {
UNIMPLEMENTED();
}
- MUST_USE_RESULT virtual Handle<Object> Delete(
+ MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
Handle<JSObject> obj,
uint32_t key,
JSReceiver::DeleteMode mode) V8_OVERRIDE = 0;
@@ -787,38 +745,45 @@ class ElementsAccessorBase : public ElementsAccessor {
}
virtual void CopyElements(
- Handle<JSObject> from_holder,
+ Handle<FixedArrayBase> from,
uint32_t from_start,
ElementsKind from_kind,
Handle<FixedArrayBase> to,
uint32_t to_start,
- int copy_size,
- Handle<FixedArrayBase> from) V8_FINAL V8_OVERRIDE {
- int packed_size = kPackedSizeNotKnown;
- if (from.is_null()) {
- from = handle(from_holder->elements());
- }
+ int copy_size) V8_FINAL V8_OVERRIDE {
+ ASSERT(!from.is_null());
+ ElementsAccessorSubclass::CopyElementsImpl(
+ from, from_start, to, from_kind, to_start, kPackedSizeNotKnown,
+ copy_size);
+ }
- if (!from_holder.is_null()) {
- bool is_packed = IsFastPackedElementsKind(from_kind) &&
- from_holder->IsJSArray();
- if (is_packed) {
- packed_size =
- Smi::cast(Handle<JSArray>::cast(from_holder)->length())->value();
- if (copy_size >= 0 && packed_size > copy_size) {
- packed_size = copy_size;
- }
+ virtual void CopyElements(
+ JSObject* from_holder,
+ uint32_t from_start,
+ ElementsKind from_kind,
+ Handle<FixedArrayBase> to,
+ uint32_t to_start,
+ int copy_size) V8_FINAL V8_OVERRIDE {
+ int packed_size = kPackedSizeNotKnown;
+ bool is_packed = IsFastPackedElementsKind(from_kind) &&
+ from_holder->IsJSArray();
+ if (is_packed) {
+ packed_size =
+ Smi::cast(JSArray::cast(from_holder)->length())->value();
+ if (copy_size >= 0 && packed_size > copy_size) {
+ packed_size = copy_size;
}
}
+ Handle<FixedArrayBase> from(from_holder->elements());
ElementsAccessorSubclass::CopyElementsImpl(
from, from_start, to, from_kind, to_start, packed_size, copy_size);
}
- MUST_USE_RESULT virtual MaybeObject* AddElementsToFixedArray(
- Object* receiver,
- JSObject* holder,
- FixedArray* to,
- FixedArrayBase* from) V8_FINAL V8_OVERRIDE {
+ virtual MaybeHandle<FixedArray> AddElementsToFixedArray(
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
+ Handle<FixedArray> to,
+ Handle<FixedArrayBase> from) V8_FINAL V8_OVERRIDE {
int len0 = to->length();
#ifdef ENABLE_SLOW_ASSERTS
if (FLAG_enable_slow_asserts) {
@@ -827,25 +792,26 @@ class ElementsAccessorBase : public ElementsAccessor {
}
}
#endif
- if (from == NULL) {
- from = holder->elements();
- }
// Optimize if 'other' is empty.
// We cannot optimize if 'this' is empty, as other may have holes.
uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(from);
if (len1 == 0) return to;
+ Isolate* isolate = from->GetIsolate();
+
// Compute how many elements are not in other.
uint32_t extra = 0;
for (uint32_t y = 0; y < len1; y++) {
uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(from, y);
if (ElementsAccessorSubclass::HasElementImpl(
receiver, holder, key, from)) {
- MaybeObject* maybe_value =
- ElementsAccessorSubclass::GetImpl(receiver, holder, key, from);
- Object* value;
- if (!maybe_value->To(&value)) return maybe_value;
+ Handle<Object> value;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, value,
+ ElementsAccessorSubclass::GetImpl(receiver, holder, key, from),
+ FixedArray);
+
ASSERT(!value->IsTheHole());
if (!HasKey(to, value)) {
extra++;
@@ -856,9 +822,7 @@ class ElementsAccessorBase : public ElementsAccessor {
if (extra == 0) return to;
// Allocate the result
- FixedArray* result;
- MaybeObject* maybe_obj = from->GetHeap()->AllocateFixedArray(len0 + extra);
- if (!maybe_obj->To(&result)) return maybe_obj;
+ Handle<FixedArray> result = isolate->factory()->NewFixedArray(len0 + extra);
// Fill in the content
{
@@ -877,12 +841,13 @@ class ElementsAccessorBase : public ElementsAccessor {
ElementsAccessorSubclass::GetKeyForIndexImpl(from, y);
if (ElementsAccessorSubclass::HasElementImpl(
receiver, holder, key, from)) {
- MaybeObject* maybe_value =
- ElementsAccessorSubclass::GetImpl(receiver, holder, key, from);
- Object* value;
- if (!maybe_value->To(&value)) return maybe_value;
+ Handle<Object> value;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, value,
+ ElementsAccessorSubclass::GetImpl(receiver, holder, key, from),
+ FixedArray);
if (!value->IsTheHole() && !HasKey(to, value)) {
- result->set(len0 + index, value);
+ result->set(len0 + index, *value);
index++;
}
}
@@ -892,21 +857,21 @@ class ElementsAccessorBase : public ElementsAccessor {
}
protected:
- static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) {
+ static uint32_t GetCapacityImpl(Handle<FixedArrayBase> backing_store) {
return backing_store->length();
}
- virtual uint32_t GetCapacity(FixedArrayBase* backing_store)
+ virtual uint32_t GetCapacity(Handle<FixedArrayBase> backing_store)
V8_FINAL V8_OVERRIDE {
return ElementsAccessorSubclass::GetCapacityImpl(backing_store);
}
- static uint32_t GetKeyForIndexImpl(FixedArrayBase* backing_store,
+ static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> backing_store,
uint32_t index) {
return index;
}
- virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store,
+ virtual uint32_t GetKeyForIndex(Handle<FixedArrayBase> backing_store,
uint32_t index) V8_FINAL V8_OVERRIDE {
return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index);
}
@@ -962,11 +927,15 @@ class FastElementsAccessor
if (length == 0) {
array->initialize_elements();
} else {
- backing_store->set_length(length);
+ int filler_size = (old_capacity - length) * ElementSize;
Address filler_start = backing_store->address() +
BackingStore::OffsetOfElementAt(length);
- int filler_size = (old_capacity - length) * ElementSize;
array->GetHeap()->CreateFillerObjectAt(filler_start, filler_size);
+
+ // We are storing the new length using release store after creating a
+ // filler for the left-over space to avoid races with the sweeper
+ // thread.
+ backing_store->synchronized_set_length(length);
}
} else {
// Otherwise, fill the unused tail with holes.
@@ -984,7 +953,7 @@ class FastElementsAccessor
if (!array->ShouldConvertToSlowElements(new_capacity)) {
FastElementsAccessorSubclass::
SetFastElementsCapacityAndLength(array, new_capacity, length);
- array->ValidateElements();
+ JSObject::ValidateElements(array);
return length_object;
}
@@ -1009,7 +978,8 @@ class FastElementsAccessor
backing_store->map() == heap->sloppy_arguments_elements_map();
if (is_sloppy_arguments_elements_map) {
backing_store = handle(
- BackingStore::cast(Handle<FixedArray>::cast(backing_store)->get(1)));
+ BackingStore::cast(Handle<FixedArray>::cast(backing_store)->get(1)),
+ isolate);
}
uint32_t length = static_cast<uint32_t>(
obj->IsJSArray()
@@ -1050,7 +1020,7 @@ class FastElementsAccessor
return isolate->factory()->true_value();
}
- virtual Handle<Object> Delete(
+ virtual MaybeHandle<Object> Delete(
Handle<JSObject> obj,
uint32_t key,
JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE {
@@ -1058,31 +1028,34 @@ class FastElementsAccessor
}
static bool HasElementImpl(
- Object* receiver,
- JSObject* holder,
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
uint32_t key,
- FixedArrayBase* backing_store) {
+ Handle<FixedArrayBase> backing_store) {
if (key >= static_cast<uint32_t>(backing_store->length())) {
return false;
}
- return !BackingStore::cast(backing_store)->is_the_hole(key);
+ return !Handle<BackingStore>::cast(backing_store)->is_the_hole(key);
}
- static void ValidateContents(JSObject* holder, int length) {
+ static void ValidateContents(Handle<JSObject> holder, int length) {
#if DEBUG
- FixedArrayBase* elements = holder->elements();
- Heap* heap = elements->GetHeap();
+ Isolate* isolate = holder->GetIsolate();
+ HandleScope scope(isolate);
+ Handle<FixedArrayBase> elements(holder->elements(), isolate);
Map* map = elements->map();
ASSERT((IsFastSmiOrObjectElementsKind(KindTraits::Kind) &&
- (map == heap->fixed_array_map() ||
- map == heap->fixed_cow_array_map())) ||
+ (map == isolate->heap()->fixed_array_map() ||
+ map == isolate->heap()->fixed_cow_array_map())) ||
(IsFastDoubleElementsKind(KindTraits::Kind) ==
- ((map == heap->fixed_array_map() && length == 0) ||
- map == heap->fixed_double_array_map())));
+ ((map == isolate->heap()->fixed_array_map() && length == 0) ||
+ map == isolate->heap()->fixed_double_array_map())));
+ DisallowHeapAllocation no_gc;
for (int i = 0; i < length; i++) {
- BackingStore* backing_store = BackingStore::cast(elements);
+ HandleScope scope(isolate);
+ Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements);
ASSERT((!IsFastSmiElementsKind(KindTraits::Kind) ||
- static_cast<Object*>(backing_store->get(i))->IsSmi()) ||
+ BackingStore::get(backing_store, i)->IsSmi()) ||
(IsFastHoleyElementsKind(KindTraits::Kind) ==
backing_store->is_the_hole(i)));
}
@@ -1091,7 +1064,7 @@ class FastElementsAccessor
};
-static inline ElementsKind ElementsKindForArray(FixedArrayBase* array) {
+static inline ElementsKind ElementsKindForArray(Handle<FixedArrayBase> array) {
switch (array->map()->instance_type()) {
case FIXED_ARRAY_TYPE:
if (array->IsDictionary()) {
@@ -1162,7 +1135,7 @@ class FastSmiOrObjectElementsAccessor
Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(from);
Handle<FixedArrayBase> arguments(
FixedArrayBase::cast(parameter_map->get(1)));
- ElementsKind from_kind = ElementsKindForArray(*arguments);
+ ElementsKind from_kind = ElementsKindForArray(arguments);
CopyElementsImpl(arguments, from_start, to, from_kind,
to_start, packed_size, copy_size);
break;
@@ -1345,37 +1318,39 @@ class TypedElementsAccessor
friend class ElementsAccessorBase<AccessorClass,
ElementsKindTraits<Kind> >;
- MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
- JSObject* obj,
- uint32_t key,
- FixedArrayBase* backing_store) {
- return
- key < AccessorClass::GetCapacityImpl(backing_store)
- ? BackingStore::cast(backing_store)->get(key)
- : backing_store->GetHeap()->undefined_value();
+ MUST_USE_RESULT static MaybeHandle<Object> GetImpl(
+ Handle<Object> receiver,
+ Handle<JSObject> obj,
+ uint32_t key,
+ Handle<FixedArrayBase> backing_store) {
+ if (key < AccessorClass::GetCapacityImpl(backing_store)) {
+ return BackingStore::get(Handle<BackingStore>::cast(backing_store), key);
+ } else {
+ return backing_store->GetIsolate()->factory()->undefined_value();
+ }
}
MUST_USE_RESULT static PropertyAttributes GetAttributesImpl(
- Object* receiver,
- JSObject* obj,
+ Handle<Object> receiver,
+ Handle<JSObject> obj,
uint32_t key,
- FixedArrayBase* backing_store) {
+ Handle<FixedArrayBase> backing_store) {
return
key < AccessorClass::GetCapacityImpl(backing_store)
? NONE : ABSENT;
}
MUST_USE_RESULT static PropertyType GetTypeImpl(
- Object* receiver,
- JSObject* obj,
+ Handle<Object> receiver,
+ Handle<JSObject> obj,
uint32_t key,
- FixedArrayBase* backing_store) {
+ Handle<FixedArrayBase> backing_store) {
return
key < AccessorClass::GetCapacityImpl(backing_store)
? FIELD : NONEXISTENT;
}
- MUST_USE_RESULT static Handle<Object> SetLengthImpl(
+ MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl(
Handle<JSObject> obj,
Handle<Object> length,
Handle<FixedArrayBase> backing_store) {
@@ -1384,7 +1359,7 @@ class TypedElementsAccessor
return obj;
}
- MUST_USE_RESULT virtual Handle<Object> Delete(
+ MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
Handle<JSObject> obj,
uint32_t key,
JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE {
@@ -1392,10 +1367,10 @@ class TypedElementsAccessor
return obj->GetIsolate()->factory()->true_value();
}
- static bool HasElementImpl(Object* receiver,
- JSObject* holder,
+ static bool HasElementImpl(Handle<Object> receiver,
+ Handle<JSObject> holder,
uint32_t key,
- FixedArrayBase* backing_store) {
+ Handle<FixedArrayBase> backing_store) {
uint32_t capacity =
AccessorClass::GetCapacityImpl(backing_store);
return key < capacity;
@@ -1430,13 +1405,14 @@ class DictionaryElementsAccessor
// Adjusts the length of the dictionary backing store and returns the new
// length according to ES5 section 15.4.5.2 behavior.
- MUST_USE_RESULT static MaybeObject* SetLengthWithoutNormalize(
- FixedArrayBase* store,
- JSArray* array,
- Object* length_object,
+ static Handle<Object> SetLengthWithoutNormalize(
+ Handle<FixedArrayBase> store,
+ Handle<JSArray> array,
+ Handle<Object> length_object,
uint32_t length) {
- SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
- Heap* heap = array->GetHeap();
+ Handle<SeededNumberDictionary> dict =
+ Handle<SeededNumberDictionary>::cast(store);
+ Isolate* isolate = array->GetIsolate();
int capacity = dict->Capacity();
uint32_t new_length = length;
uint32_t old_length = static_cast<uint32_t>(array->length()->Number());
@@ -1444,6 +1420,7 @@ class DictionaryElementsAccessor
// Find last non-deletable element in range of elements to be
// deleted and adjust range accordingly.
for (int i = 0; i < capacity; i++) {
+ DisallowHeapAllocation no_gc;
Object* key = dict->KeyAt(i);
if (key->IsNumber()) {
uint32_t number = static_cast<uint32_t>(key->Number());
@@ -1454,8 +1431,7 @@ class DictionaryElementsAccessor
}
}
if (new_length != length) {
- MaybeObject* maybe_object = heap->NumberFromUint32(new_length);
- if (!maybe_object->To(&length_object)) return maybe_object;
+ length_object = isolate->factory()->NewNumberFromUint(new_length);
}
}
@@ -1463,13 +1439,12 @@ class DictionaryElementsAccessor
// If the length of a slow array is reset to zero, we clear
// the array and flush backing storage. This has the added
// benefit that the array returns to fast mode.
- Object* obj;
- MaybeObject* maybe_obj = array->ResetElements();
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+ JSObject::ResetElements(array);
} else {
+ DisallowHeapAllocation no_gc;
// Remove elements that should be deleted.
int removed_entries = 0;
- Object* the_hole_value = heap->the_hole_value();
+ Handle<Object> the_hole_value = isolate->factory()->the_hole_value();
for (int i = 0; i < capacity; i++) {
Object* key = dict->KeyAt(i);
if (key->IsNumber()) {
@@ -1487,71 +1462,46 @@ class DictionaryElementsAccessor
return length_object;
}
- // TODO(ishell): Temporary wrapper until handlified.
- MUST_USE_RESULT static Handle<Object> SetLengthWithoutNormalize(
- Handle<FixedArrayBase> store,
- Handle<JSArray> array,
- Handle<Object> length_object,
- uint32_t length) {
- CALL_HEAP_FUNCTION(array->GetIsolate(),
- SetLengthWithoutNormalize(
- *store, *array, *length_object, length),
- Object);
- }
-
- MUST_USE_RESULT static MaybeObject* DeleteCommon(
- JSObject* obj,
+ MUST_USE_RESULT static MaybeHandle<Object> DeleteCommon(
+ Handle<JSObject> obj,
uint32_t key,
JSReceiver::DeleteMode mode) {
Isolate* isolate = obj->GetIsolate();
- Heap* heap = isolate->heap();
- FixedArray* backing_store = FixedArray::cast(obj->elements());
+ Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()),
+ isolate);
bool is_arguments =
(obj->GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS);
if (is_arguments) {
- backing_store = FixedArray::cast(backing_store->get(1));
+ backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate);
}
- SeededNumberDictionary* dictionary =
- SeededNumberDictionary::cast(backing_store);
+ Handle<SeededNumberDictionary> dictionary =
+ Handle<SeededNumberDictionary>::cast(backing_store);
int entry = dictionary->FindEntry(key);
if (entry != SeededNumberDictionary::kNotFound) {
- Object* result = dictionary->DeleteProperty(entry, mode);
- if (result == heap->false_value()) {
+ Handle<Object> result =
+ SeededNumberDictionary::DeleteProperty(dictionary, entry, mode);
+ if (*result == *isolate->factory()->false_value()) {
if (mode == JSObject::STRICT_DELETION) {
// Deleting a non-configurable property in strict mode.
- HandleScope scope(isolate);
- Handle<Object> holder(obj, isolate);
Handle<Object> name = isolate->factory()->NewNumberFromUint(key);
- Handle<Object> args[2] = { name, holder };
+ Handle<Object> args[2] = { name, obj };
Handle<Object> error =
isolate->factory()->NewTypeError("strict_delete_property",
HandleVector(args, 2));
- return isolate->Throw(*error);
+ return isolate->Throw<Object>(error);
}
- return heap->false_value();
- }
- MaybeObject* maybe_elements = dictionary->Shrink(key);
- FixedArray* new_elements = NULL;
- if (!maybe_elements->To(&new_elements)) {
- return maybe_elements;
+ return isolate->factory()->false_value();
}
+ Handle<FixedArray> new_elements =
+ SeededNumberDictionary::Shrink(dictionary, key);
+
if (is_arguments) {
- FixedArray::cast(obj->elements())->set(1, new_elements);
+ FixedArray::cast(obj->elements())->set(1, *new_elements);
} else {
- obj->set_elements(new_elements);
+ obj->set_elements(*new_elements);
}
}
- return heap->true_value();
- }
-
- // TODO(ishell): Temporary wrapper until handlified.
- MUST_USE_RESULT static Handle<Object> DeleteCommon(
- Handle<JSObject> obj,
- uint32_t key,
- JSReceiver::DeleteMode mode) {
- CALL_HEAP_FUNCTION(obj->GetIsolate(),
- DeleteCommon(*obj, key, mode),
- Object);
+ return isolate->factory()->true_value();
}
static void CopyElementsImpl(Handle<FixedArrayBase> from,
@@ -1569,42 +1519,42 @@ class DictionaryElementsAccessor
friend class ElementsAccessorBase<DictionaryElementsAccessor,
ElementsKindTraits<DICTIONARY_ELEMENTS> >;
- MUST_USE_RESULT virtual Handle<Object> Delete(
+ MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
Handle<JSObject> obj,
uint32_t key,
JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE {
return DeleteCommon(obj, key, mode);
}
- MUST_USE_RESULT static MaybeObject* GetImpl(
- Object* receiver,
- JSObject* obj,
+ MUST_USE_RESULT static MaybeHandle<Object> GetImpl(
+ Handle<Object> receiver,
+ Handle<JSObject> obj,
uint32_t key,
- FixedArrayBase* store) {
- SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
+ Handle<FixedArrayBase> store) {
+ Handle<SeededNumberDictionary> backing_store =
+ Handle<SeededNumberDictionary>::cast(store);
+ Isolate* isolate = backing_store->GetIsolate();
int entry = backing_store->FindEntry(key);
if (entry != SeededNumberDictionary::kNotFound) {
- Object* element = backing_store->ValueAt(entry);
+ Handle<Object> element(backing_store->ValueAt(entry), isolate);
PropertyDetails details = backing_store->DetailsAt(entry);
if (details.type() == CALLBACKS) {
- return obj->GetElementWithCallback(receiver,
- element,
- key,
- obj);
+ return JSObject::GetElementWithCallback(
+ obj, receiver, element, key, obj);
} else {
return element;
}
}
- return obj->GetHeap()->the_hole_value();
+ return isolate->factory()->the_hole_value();
}
MUST_USE_RESULT static PropertyAttributes GetAttributesImpl(
- Object* receiver,
- JSObject* obj,
+ Handle<Object> receiver,
+ Handle<JSObject> obj,
uint32_t key,
- FixedArrayBase* backing_store) {
- SeededNumberDictionary* dictionary =
- SeededNumberDictionary::cast(backing_store);
+ Handle<FixedArrayBase> backing_store) {
+ Handle<SeededNumberDictionary> dictionary =
+ Handle<SeededNumberDictionary>::cast(backing_store);
int entry = dictionary->FindEntry(key);
if (entry != SeededNumberDictionary::kNotFound) {
return dictionary->DetailsAt(entry).attributes();
@@ -1613,11 +1563,12 @@ class DictionaryElementsAccessor
}
MUST_USE_RESULT static PropertyType GetTypeImpl(
- Object* receiver,
- JSObject* obj,
+ Handle<Object> receiver,
+ Handle<JSObject> obj,
uint32_t key,
- FixedArrayBase* store) {
- SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
+ Handle<FixedArrayBase> store) {
+ Handle<SeededNumberDictionary> backing_store =
+ Handle<SeededNumberDictionary>::cast(store);
int entry = backing_store->FindEntry(key);
if (entry != SeededNumberDictionary::kNotFound) {
return backing_store->DetailsAt(entry).type();
@@ -1625,32 +1576,36 @@ class DictionaryElementsAccessor
return NONEXISTENT;
}
- MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl(
- Object* receiver,
- JSObject* obj,
+ MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl(
+ Handle<Object> receiver,
+ Handle<JSObject> obj,
uint32_t key,
- FixedArrayBase* store) {
- SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
+ Handle<FixedArrayBase> store) {
+ Handle<SeededNumberDictionary> backing_store =
+ Handle<SeededNumberDictionary>::cast(store);
int entry = backing_store->FindEntry(key);
if (entry != SeededNumberDictionary::kNotFound &&
backing_store->DetailsAt(entry).type() == CALLBACKS &&
backing_store->ValueAt(entry)->IsAccessorPair()) {
- return AccessorPair::cast(backing_store->ValueAt(entry));
+ return handle(AccessorPair::cast(backing_store->ValueAt(entry)));
}
- return NULL;
+ return MaybeHandle<AccessorPair>();
}
- static bool HasElementImpl(Object* receiver,
- JSObject* holder,
+ static bool HasElementImpl(Handle<Object> receiver,
+ Handle<JSObject> holder,
uint32_t key,
- FixedArrayBase* backing_store) {
- return SeededNumberDictionary::cast(backing_store)->FindEntry(key) !=
- SeededNumberDictionary::kNotFound;
+ Handle<FixedArrayBase> store) {
+ Handle<SeededNumberDictionary> backing_store =
+ Handle<SeededNumberDictionary>::cast(store);
+ return backing_store->FindEntry(key) != SeededNumberDictionary::kNotFound;
}
- static uint32_t GetKeyForIndexImpl(FixedArrayBase* store,
+ static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> store,
uint32_t index) {
- SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
+ DisallowHeapAllocation no_gc;
+ Handle<SeededNumberDictionary> dict =
+ Handle<SeededNumberDictionary>::cast(store);
Object* key = dict->KeyAt(index);
return Smi::cast(key)->value();
}
@@ -1670,31 +1625,38 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
SloppyArgumentsElementsAccessor,
ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >;
- MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
- JSObject* obj,
- uint32_t key,
- FixedArrayBase* parameters) {
- FixedArray* parameter_map = FixedArray::cast(parameters);
- Object* probe = GetParameterMapArg(obj, parameter_map, key);
+ MUST_USE_RESULT static MaybeHandle<Object> GetImpl(
+ Handle<Object> receiver,
+ Handle<JSObject> obj,
+ uint32_t key,
+ Handle<FixedArrayBase> parameters) {
+ Isolate* isolate = obj->GetIsolate();
+ Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
+ Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key);
if (!probe->IsTheHole()) {
+ DisallowHeapAllocation no_gc;
Context* context = Context::cast(parameter_map->get(0));
- int context_index = Smi::cast(probe)->value();
+ int context_index = Handle<Smi>::cast(probe)->value();
ASSERT(!context->get(context_index)->IsTheHole());
- return context->get(context_index);
+ return handle(context->get(context_index), isolate);
} else {
// Object is not mapped, defer to the arguments.
- FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
- MaybeObject* maybe_result = ElementsAccessor::ForArray(arguments)->Get(
- receiver, obj, key, arguments);
- Object* result;
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)),
+ isolate);
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ ElementsAccessor::ForArray(arguments)->Get(
+ receiver, obj, key, arguments),
+ Object);
// Elements of the arguments object in slow mode might be slow aliases.
if (result->IsAliasedArgumentsEntry()) {
- AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(result);
+ DisallowHeapAllocation no_gc;
+ AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result);
Context* context = Context::cast(parameter_map->get(0));
int context_index = entry->aliased_context_slot();
ASSERT(!context->get(context_index)->IsTheHole());
- return context->get(context_index);
+ return handle(context->get(context_index), isolate);
} else {
return result;
}
@@ -1702,57 +1664,57 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
}
MUST_USE_RESULT static PropertyAttributes GetAttributesImpl(
- Object* receiver,
- JSObject* obj,
+ Handle<Object> receiver,
+ Handle<JSObject> obj,
uint32_t key,
- FixedArrayBase* backing_store) {
- FixedArray* parameter_map = FixedArray::cast(backing_store);
- Object* probe = GetParameterMapArg(obj, parameter_map, key);
+ Handle<FixedArrayBase> backing_store) {
+ Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store);
+ Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key);
if (!probe->IsTheHole()) {
return NONE;
} else {
// If not aliased, check the arguments.
- FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+ Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
return ElementsAccessor::ForArray(arguments)->GetAttributes(
receiver, obj, key, arguments);
}
}
MUST_USE_RESULT static PropertyType GetTypeImpl(
- Object* receiver,
- JSObject* obj,
+ Handle<Object> receiver,
+ Handle<JSObject> obj,
uint32_t key,
- FixedArrayBase* parameters) {
- FixedArray* parameter_map = FixedArray::cast(parameters);
- Object* probe = GetParameterMapArg(obj, parameter_map, key);
+ Handle<FixedArrayBase> parameters) {
+ Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
+ Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key);
if (!probe->IsTheHole()) {
return FIELD;
} else {
// If not aliased, check the arguments.
- FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+ Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
return ElementsAccessor::ForArray(arguments)->GetType(
receiver, obj, key, arguments);
}
}
- MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl(
- Object* receiver,
- JSObject* obj,
+ MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl(
+ Handle<Object> receiver,
+ Handle<JSObject> obj,
uint32_t key,
- FixedArrayBase* parameters) {
- FixedArray* parameter_map = FixedArray::cast(parameters);
- Object* probe = GetParameterMapArg(obj, parameter_map, key);
+ Handle<FixedArrayBase> parameters) {
+ Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
+ Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key);
if (!probe->IsTheHole()) {
- return NULL;
+ return MaybeHandle<AccessorPair>();
} else {
// If not aliased, check the arguments.
- FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+ Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
return ElementsAccessor::ForArray(arguments)->GetAccessorPair(
receiver, obj, key, arguments);
}
}
- MUST_USE_RESULT static Handle<Object> SetLengthImpl(
+ MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl(
Handle<JSObject> obj,
Handle<Object> length,
Handle<FixedArrayBase> parameter_map) {
@@ -1762,7 +1724,7 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
return obj;
}
- MUST_USE_RESULT virtual Handle<Object> Delete(
+ MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
Handle<JSObject> obj,
uint32_t key,
JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE {
@@ -1798,47 +1760,42 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
UNREACHABLE();
}
- static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) {
- FixedArray* parameter_map = FixedArray::cast(backing_store);
- FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
+ static uint32_t GetCapacityImpl(Handle<FixedArrayBase> backing_store) {
+ Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store);
+ Handle<FixedArrayBase> arguments(
+ FixedArrayBase::cast(parameter_map->get(1)));
return Max(static_cast<uint32_t>(parameter_map->length() - 2),
ForArray(arguments)->GetCapacity(arguments));
}
- static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict,
+ static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> dict,
uint32_t index) {
return index;
}
- static bool HasElementImpl(Object* receiver,
- JSObject* holder,
+ static bool HasElementImpl(Handle<Object> receiver,
+ Handle<JSObject> holder,
uint32_t key,
- FixedArrayBase* parameters) {
- FixedArray* parameter_map = FixedArray::cast(parameters);
- Object* probe = GetParameterMapArg(holder, parameter_map, key);
+ Handle<FixedArrayBase> parameters) {
+ Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
+ Handle<Object> probe = GetParameterMapArg(holder, parameter_map, key);
if (!probe->IsTheHole()) {
return true;
} else {
- FixedArrayBase* arguments =
- FixedArrayBase::cast(FixedArray::cast(parameter_map)->get(1));
+ Isolate* isolate = holder->GetIsolate();
+ Handle<FixedArrayBase> arguments(FixedArrayBase::cast(
+ Handle<FixedArray>::cast(parameter_map)->get(1)), isolate);
ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
- return !accessor->Get(receiver, holder, key, arguments)->IsTheHole();
+ Handle<Object> value;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, value,
+ accessor->Get(receiver, holder, key, arguments),
+ false);
+ return !value->IsTheHole();
}
}
private:
- // TODO(ishell): remove when all usages are handlified.
- static Object* GetParameterMapArg(JSObject* holder,
- FixedArray* parameter_map,
- uint32_t key) {
- uint32_t length = holder->IsJSArray()
- ? Smi::cast(JSArray::cast(holder)->length())->value()
- : parameter_map->length();
- return key < (length - 2)
- ? parameter_map->get(key + 2)
- : parameter_map->GetHeap()->the_hole_value();
- }
-
static Handle<Object> GetParameterMapArg(Handle<JSObject> holder,
Handle<FixedArray> parameter_map,
uint32_t key) {
@@ -1853,7 +1810,7 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
};
-ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) {
+ElementsAccessor* ElementsAccessor::ForArray(Handle<FixedArrayBase> array) {
return elements_accessors_[ElementsKindForArray(array)];
}
@@ -1881,8 +1838,9 @@ void ElementsAccessor::TearDown() {
template <typename ElementsAccessorSubclass, typename ElementsKindTraits>
-MUST_USE_RESULT Handle<Object> ElementsAccessorBase<ElementsAccessorSubclass,
- ElementsKindTraits>::
+MUST_USE_RESULT
+MaybeHandle<Object> ElementsAccessorBase<ElementsAccessorSubclass,
+ ElementsKindTraits>::
SetLengthImpl(Handle<JSObject> obj,
Handle<Object> length,
Handle<FixedArrayBase> backing_store) {
@@ -1890,14 +1848,15 @@ MUST_USE_RESULT Handle<Object> ElementsAccessorBase<ElementsAccessorSubclass,
Handle<JSArray> array = Handle<JSArray>::cast(obj);
// Fast case: The new length fits into a Smi.
- Handle<Object> smi_length = Object::ToSmi(isolate, length);
+ Handle<Object> smi_length;
- if (!smi_length.is_null() && smi_length->IsSmi()) {
+ if (Object::ToSmi(isolate, length).ToHandle(&smi_length) &&
+ smi_length->IsSmi()) {
const int value = Handle<Smi>::cast(smi_length)->value();
if (value >= 0) {
Handle<Object> new_length = ElementsAccessorSubclass::
SetLengthWithoutNormalize(backing_store, array, smi_length, value);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, new_length, new_length);
+ ASSERT(!new_length.is_null());
// even though the proposed length was a smi, new_length could
// still be a heap number because SetLengthWithoutNormalize doesn't
@@ -1924,11 +1883,11 @@ MUST_USE_RESULT Handle<Object> ElementsAccessorBase<ElementsAccessorSubclass,
if (length->ToArrayIndex(&value)) {
Handle<SeededNumberDictionary> dictionary =
JSObject::NormalizeElements(array);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, dictionary, dictionary);
+ ASSERT(!dictionary.is_null());
Handle<Object> new_length = DictionaryElementsAccessor::
SetLengthWithoutNormalize(dictionary, array, length, value);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, new_length, new_length);
+ ASSERT(!new_length.is_null());
ASSERT(new_length->IsNumber());
array->set_length(*new_length);
@@ -1947,8 +1906,8 @@ MUST_USE_RESULT Handle<Object> ElementsAccessorBase<ElementsAccessorSubclass,
}
-Handle<Object> ArrayConstructInitializeElements(Handle<JSArray> array,
- Arguments* args) {
+MaybeHandle<Object> ArrayConstructInitializeElements(Handle<JSArray> array,
+ Arguments* args) {
// Optimize the case where there is one argument and the argument is a
// small smi.
if (args->length() == 1) {
diff --git a/deps/v8/src/elements.h b/deps/v8/src/elements.h
index 44644abd92..88f5db8c5b 100644
--- a/deps/v8/src/elements.h
+++ b/deps/v8/src/elements.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ELEMENTS_H_
#define V8_ELEMENTS_H_
@@ -48,35 +25,43 @@ class ElementsAccessor {
// Checks the elements of an object for consistency, asserting when a problem
// is found.
- virtual void Validate(JSObject* obj) = 0;
+ virtual void Validate(Handle<JSObject> obj) = 0;
// Returns true if a holder contains an element with the specified key
// without iterating up the prototype chain. The caller can optionally pass
// in the backing store to use for the check, which must be compatible with
// the ElementsKind of the ElementsAccessor. If backing_store is NULL, the
// holder->elements() is used as the backing store.
- virtual bool HasElement(Object* receiver,
- JSObject* holder,
- uint32_t key,
- FixedArrayBase* backing_store = NULL) = 0;
+ virtual bool HasElement(
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
+ uint32_t key,
+ Handle<FixedArrayBase> backing_store) = 0;
+
+ inline bool HasElement(
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
+ uint32_t key) {
+ return HasElement(receiver, holder, key, handle(holder->elements()));
+ }
// Returns the element with the specified key or undefined if there is no such
// element. This method doesn't iterate up the prototype chain. The caller
// can optionally pass in the backing store to use for the check, which must
// be compatible with the ElementsKind of the ElementsAccessor. If
// backing_store is NULL, the holder->elements() is used as the backing store.
- MUST_USE_RESULT virtual Handle<Object> Get(
+ MUST_USE_RESULT virtual MaybeHandle<Object> Get(
Handle<Object> receiver,
Handle<JSObject> holder,
uint32_t key,
- Handle<FixedArrayBase> backing_store =
- Handle<FixedArrayBase>::null()) = 0;
+ Handle<FixedArrayBase> backing_store) = 0;
- MUST_USE_RESULT virtual MaybeObject* Get(
- Object* receiver,
- JSObject* holder,
- uint32_t key,
- FixedArrayBase* backing_store = NULL) = 0;
+ MUST_USE_RESULT inline MaybeHandle<Object> Get(
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
+ uint32_t key) {
+ return Get(receiver, holder, key, handle(holder->elements()));
+ }
// Returns an element's attributes, or ABSENT if there is no such
// element. This method doesn't iterate up the prototype chain. The caller
@@ -84,10 +69,17 @@ class ElementsAccessor {
// be compatible with the ElementsKind of the ElementsAccessor. If
// backing_store is NULL, the holder->elements() is used as the backing store.
MUST_USE_RESULT virtual PropertyAttributes GetAttributes(
- Object* receiver,
- JSObject* holder,
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
uint32_t key,
- FixedArrayBase* backing_store = NULL) = 0;
+ Handle<FixedArrayBase> backing_store) = 0;
+
+ MUST_USE_RESULT inline PropertyAttributes GetAttributes(
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
+ uint32_t key) {
+ return GetAttributes(receiver, holder, key, handle(holder->elements()));
+ }
// Returns an element's type, or NONEXISTENT if there is no such
// element. This method doesn't iterate up the prototype chain. The caller
@@ -95,28 +87,42 @@ class ElementsAccessor {
// be compatible with the ElementsKind of the ElementsAccessor. If
// backing_store is NULL, the holder->elements() is used as the backing store.
MUST_USE_RESULT virtual PropertyType GetType(
- Object* receiver,
- JSObject* holder,
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
uint32_t key,
- FixedArrayBase* backing_store = NULL) = 0;
+ Handle<FixedArrayBase> backing_store) = 0;
+
+ MUST_USE_RESULT inline PropertyType GetType(
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
+ uint32_t key) {
+ return GetType(receiver, holder, key, handle(holder->elements()));
+ }
// Returns an element's accessors, or NULL if the element does not exist or
// is plain. This method doesn't iterate up the prototype chain. The caller
// can optionally pass in the backing store to use for the check, which must
// be compatible with the ElementsKind of the ElementsAccessor. If
// backing_store is NULL, the holder->elements() is used as the backing store.
- MUST_USE_RESULT virtual AccessorPair* GetAccessorPair(
- Object* receiver,
- JSObject* holder,
+ MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair(
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
uint32_t key,
- FixedArrayBase* backing_store = NULL) = 0;
+ Handle<FixedArrayBase> backing_store) = 0;
+
+ MUST_USE_RESULT inline MaybeHandle<AccessorPair> GetAccessorPair(
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
+ uint32_t key) {
+ return GetAccessorPair(receiver, holder, key, handle(holder->elements()));
+ }
// Modifies the length data property as specified for JSArrays and resizes the
// underlying backing store accordingly. The method honors the semantics of
// changing array sizes as defined in EcmaScript 5.1 15.4.5.2, i.e. array that
// have non-deletable elements can only be shrunk to the size of highest
// element that is non-deletable.
- MUST_USE_RESULT virtual Handle<Object> SetLength(
+ MUST_USE_RESULT virtual MaybeHandle<Object> SetLength(
Handle<JSArray> holder,
Handle<Object> new_length) = 0;
@@ -132,7 +138,7 @@ class ElementsAccessor {
int length) = 0;
// Deletes an element in an object, returning a new elements backing store.
- MUST_USE_RESULT virtual Handle<Object> Delete(
+ MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
Handle<JSObject> holder,
uint32_t key,
JSReceiver::DeleteMode mode) = 0;
@@ -151,28 +157,45 @@ class ElementsAccessor {
// store is available, it can be passed in source and source_holder is
// ignored.
virtual void CopyElements(
- Handle<JSObject> source_holder,
+ Handle<FixedArrayBase> source,
+ uint32_t source_start,
+ ElementsKind source_kind,
+ Handle<FixedArrayBase> destination,
+ uint32_t destination_start,
+ int copy_size) = 0;
+
+ // TODO(ishell): Keeping |source_holder| parameter in a non-handlified form
+ // helps avoiding ArrayConcat() builtin performance degradation.
+ // Revisit this later.
+ virtual void CopyElements(
+ JSObject* source_holder,
uint32_t source_start,
ElementsKind source_kind,
Handle<FixedArrayBase> destination,
uint32_t destination_start,
- int copy_size,
- Handle<FixedArrayBase> source = Handle<FixedArrayBase>::null()) = 0;
+ int copy_size) = 0;
- void CopyElements(
+ inline void CopyElements(
Handle<JSObject> from_holder,
Handle<FixedArrayBase> to,
- ElementsKind from_kind,
- Handle<FixedArrayBase> from = Handle<FixedArrayBase>::null()) {
- CopyElements(from_holder, 0, from_kind, to, 0,
- kCopyToEndAndInitializeToHole, from);
+ ElementsKind from_kind) {
+ CopyElements(
+ *from_holder, 0, from_kind, to, 0, kCopyToEndAndInitializeToHole);
}
- MUST_USE_RESULT virtual MaybeObject* AddElementsToFixedArray(
- Object* receiver,
- JSObject* holder,
- FixedArray* to,
- FixedArrayBase* from = NULL) = 0;
+ MUST_USE_RESULT virtual MaybeHandle<FixedArray> AddElementsToFixedArray(
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
+ Handle<FixedArray> to,
+ Handle<FixedArrayBase> from) = 0;
+
+ MUST_USE_RESULT inline MaybeHandle<FixedArray> AddElementsToFixedArray(
+ Handle<Object> receiver,
+ Handle<JSObject> holder,
+ Handle<FixedArray> to) {
+ return AddElementsToFixedArray(
+ receiver, holder, to, handle(holder->elements()));
+ }
// Returns a shared ElementsAccessor for the specified ElementsKind.
static ElementsAccessor* ForKind(ElementsKind elements_kind) {
@@ -180,7 +203,7 @@ class ElementsAccessor {
return elements_accessors_[elements_kind];
}
- static ElementsAccessor* ForArray(FixedArrayBase* array);
+ static ElementsAccessor* ForArray(Handle<FixedArrayBase> array);
static void InitializeOncePerProcess();
static void TearDown();
@@ -188,7 +211,7 @@ class ElementsAccessor {
protected:
friend class SloppyArgumentsElementsAccessor;
- virtual uint32_t GetCapacity(FixedArrayBase* backing_store) = 0;
+ virtual uint32_t GetCapacity(Handle<FixedArrayBase> backing_store) = 0;
// Element handlers distinguish between indexes and keys when they manipulate
// elements. Indexes refer to elements in terms of their location in the
@@ -198,7 +221,7 @@ class ElementsAccessor {
// keys are equivalent to indexes, and GetKeyForIndex returns the same value
// it is passed. In the NumberDictionary ElementsAccessor, GetKeyForIndex maps
// the index to a key using the KeyAt method on the NumberDictionary.
- virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store,
+ virtual uint32_t GetKeyForIndex(Handle<FixedArrayBase> backing_store,
uint32_t index) = 0;
private:
@@ -208,11 +231,12 @@ class ElementsAccessor {
DISALLOW_COPY_AND_ASSIGN(ElementsAccessor);
};
-void CheckArrayAbuse(JSObject* obj, const char* op, uint32_t key,
+void CheckArrayAbuse(Handle<JSObject> obj, const char* op, uint32_t key,
bool allow_appending = false);
-Handle<Object> ArrayConstructInitializeElements(Handle<JSArray> array,
- Arguments* args);
+MUST_USE_RESULT MaybeHandle<Object> ArrayConstructInitializeElements(
+ Handle<JSArray> array,
+ Arguments* args);
} } // namespace v8::internal
diff --git a/deps/v8/src/execution.cc b/deps/v8/src/execution.cc
index 7442d1732f..b74ef4d62e 100644
--- a/deps/v8/src/execution.cc
+++ b/deps/v8/src/execution.cc
@@ -1,49 +1,18 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <stdlib.h>
-
-#include "v8.h"
-
-#include "api.h"
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "execution.h"
+
#include "bootstrapper.h"
#include "codegen.h"
-#include "debug.h"
#include "deoptimizer.h"
#include "isolate-inl.h"
-#include "runtime-profiler.h"
-#include "simulator.h"
-#include "v8threads.h"
#include "vm-state-inl.h"
namespace v8 {
namespace internal {
-
StackGuard::StackGuard()
: isolate_(NULL) {
}
@@ -67,12 +36,12 @@ void StackGuard::reset_limits(const ExecutionAccess& lock) {
}
-static Handle<Object> Invoke(bool is_construct,
- Handle<JSFunction> function,
- Handle<Object> receiver,
- int argc,
- Handle<Object> args[],
- bool* has_pending_exception) {
+MUST_USE_RESULT static MaybeHandle<Object> Invoke(
+ bool is_construct,
+ Handle<JSFunction> function,
+ Handle<Object> receiver,
+ int argc,
+ Handle<Object> args[]) {
Isolate* isolate = function->GetIsolate();
// Entering JavaScript.
@@ -80,13 +49,12 @@ static Handle<Object> Invoke(bool is_construct,
CHECK(AllowJavascriptExecution::IsAllowed(isolate));
if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) {
isolate->ThrowIllegalOperation();
- *has_pending_exception = true;
isolate->ReportPendingMessages();
- return Handle<Object>();
+ return MaybeHandle<Object>();
}
// Placeholder for return value.
- MaybeObject* value = reinterpret_cast<Object*>(kZapValue);
+ Object* value = NULL;
typedef Object* (*JSEntryFunction)(byte* entry,
Object* function,
@@ -127,41 +95,36 @@ static Handle<Object> Invoke(bool is_construct,
}
#ifdef VERIFY_HEAP
- value->Verify();
+ value->ObjectVerify();
#endif
// Update the pending exception flag and return the value.
- *has_pending_exception = value->IsException();
- ASSERT(*has_pending_exception == isolate->has_pending_exception());
- if (*has_pending_exception) {
+ bool has_exception = value->IsException();
+ ASSERT(has_exception == isolate->has_pending_exception());
+ if (has_exception) {
isolate->ReportPendingMessages();
-#ifdef ENABLE_DEBUGGER_SUPPORT
// Reset stepping state when script exits with uncaught exception.
if (isolate->debugger()->IsDebuggerActive()) {
isolate->debug()->ClearStepping();
}
-#endif // ENABLE_DEBUGGER_SUPPORT
- return Handle<Object>();
+ return MaybeHandle<Object>();
} else {
isolate->clear_pending_message();
}
- return Handle<Object>(value->ToObjectUnchecked(), isolate);
+ return Handle<Object>(value, isolate);
}
-Handle<Object> Execution::Call(Isolate* isolate,
- Handle<Object> callable,
- Handle<Object> receiver,
- int argc,
- Handle<Object> argv[],
- bool* pending_exception,
- bool convert_receiver) {
- *pending_exception = false;
-
+MaybeHandle<Object> Execution::Call(Isolate* isolate,
+ Handle<Object> callable,
+ Handle<Object> receiver,
+ int argc,
+ Handle<Object> argv[],
+ bool convert_receiver) {
if (!callable->IsJSFunction()) {
- callable = TryGetFunctionDelegate(isolate, callable, pending_exception);
- if (*pending_exception) return callable;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, callable, TryGetFunctionDelegate(isolate, callable), Object);
}
Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
@@ -178,29 +141,27 @@ Handle<Object> Execution::Call(Isolate* isolate,
receiver = Handle<Object>(global, func->GetIsolate());
}
} else {
- receiver = ToObject(isolate, receiver, pending_exception);
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, receiver, ToObject(isolate, receiver), Object);
}
- if (*pending_exception) return callable;
}
- return Invoke(false, func, receiver, argc, argv, pending_exception);
+ return Invoke(false, func, receiver, argc, argv);
}
-Handle<Object> Execution::New(Handle<JSFunction> func,
- int argc,
- Handle<Object> argv[],
- bool* pending_exception) {
- return Invoke(true, func, func->GetIsolate()->global_object(), argc, argv,
- pending_exception);
+MaybeHandle<Object> Execution::New(Handle<JSFunction> func,
+ int argc,
+ Handle<Object> argv[]) {
+ return Invoke(true, func, func->GetIsolate()->global_object(), argc, argv);
}
-Handle<Object> Execution::TryCall(Handle<JSFunction> func,
- Handle<Object> receiver,
- int argc,
- Handle<Object> args[],
- bool* caught_exception) {
+MaybeHandle<Object> Execution::TryCall(Handle<JSFunction> func,
+ Handle<Object> receiver,
+ int argc,
+ Handle<Object> args[],
+ Handle<Object>* exception_out) {
// Enter a try-block while executing the JavaScript code. To avoid
// duplicate error printing it must be non-verbose. Also, to avoid
// creating message objects during stack overflow we shouldn't
@@ -208,30 +169,30 @@ Handle<Object> Execution::TryCall(Handle<JSFunction> func,
v8::TryCatch catcher;
catcher.SetVerbose(false);
catcher.SetCaptureMessage(false);
- *caught_exception = false;
// Get isolate now, because handle might be persistent
// and get destroyed in the next call.
Isolate* isolate = func->GetIsolate();
- Handle<Object> result = Invoke(false, func, receiver, argc, args,
- caught_exception);
+ MaybeHandle<Object> maybe_result = Invoke(false, func, receiver, argc, args);
- if (*caught_exception) {
+ if (maybe_result.is_null()) {
ASSERT(catcher.HasCaught());
ASSERT(isolate->has_pending_exception());
ASSERT(isolate->external_caught_exception());
- if (isolate->pending_exception() ==
- isolate->heap()->termination_exception()) {
- result = isolate->factory()->termination_exception();
- } else {
- result = v8::Utils::OpenHandle(*catcher.Exception());
+ if (exception_out != NULL) {
+ if (isolate->pending_exception() ==
+ isolate->heap()->termination_exception()) {
+ *exception_out = isolate->factory()->termination_exception();
+ } else {
+ *exception_out = v8::Utils::OpenHandle(*catcher.Exception());
+ }
}
isolate->OptionalRescheduleException(true);
}
ASSERT(!isolate->has_pending_exception());
ASSERT(!isolate->external_caught_exception());
- return result;
+ return maybe_result;
}
@@ -262,9 +223,8 @@ Handle<Object> Execution::GetFunctionDelegate(Isolate* isolate,
}
-Handle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate,
- Handle<Object> object,
- bool* has_pending_exception) {
+MaybeHandle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate,
+ Handle<Object> object) {
ASSERT(!object->IsJSFunction());
// If object is a function proxy, get its handler. Iterate if necessary.
@@ -286,10 +246,8 @@ Handle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate,
// throw a non-callable exception.
i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
"called_non_callable", i::HandleVector<i::Object>(&object, 1));
- isolate->Throw(*error_obj);
- *has_pending_exception = true;
- return isolate->factory()->undefined_value();
+ return isolate->Throw<Object>(error_obj);
}
@@ -319,10 +277,8 @@ Handle<Object> Execution::GetConstructorDelegate(Isolate* isolate,
}
-Handle<Object> Execution::TryGetConstructorDelegate(
- Isolate* isolate,
- Handle<Object> object,
- bool* has_pending_exception) {
+MaybeHandle<Object> Execution::TryGetConstructorDelegate(
+ Isolate* isolate, Handle<Object> object) {
ASSERT(!object->IsJSFunction());
// If you return a function from here, it will be called when an
@@ -347,38 +303,29 @@ Handle<Object> Execution::TryGetConstructorDelegate(
// throw a non-callable exception.
i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
"called_non_callable", i::HandleVector<i::Object>(&object, 1));
- isolate->Throw(*error_obj);
- *has_pending_exception = true;
-
- return isolate->factory()->undefined_value();
+ return isolate->Throw<Object>(error_obj);
}
void Execution::RunMicrotasks(Isolate* isolate) {
ASSERT(isolate->microtask_pending());
- bool threw = false;
Execution::Call(
isolate,
isolate->run_microtasks(),
isolate->factory()->undefined_value(),
0,
- NULL,
- &threw);
- ASSERT(!threw);
+ NULL).Check();
}
void Execution::EnqueueMicrotask(Isolate* isolate, Handle<Object> microtask) {
- bool threw = false;
Handle<Object> args[] = { microtask };
Execution::Call(
isolate,
- isolate->enqueue_external_microtask(),
+ isolate->enqueue_microtask(),
isolate->factory()->undefined_value(),
1,
- args,
- &threw);
- ASSERT(!threw);
+ args).Check();
}
@@ -529,7 +476,6 @@ void StackGuard::DeoptMarkedAllocationSites() {
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
bool StackGuard::IsDebugBreak() {
ExecutionAccess access(isolate_);
return thread_local_.interrupt_flags_ & DEBUGBREAK;
@@ -550,13 +496,11 @@ bool StackGuard::IsDebugCommand() {
void StackGuard::DebugCommand() {
- if (FLAG_debugger_auto_break) {
- ExecutionAccess access(isolate_);
- thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
- set_interrupt_limits(access);
- }
+ ExecutionAccess access(isolate_);
+ thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
+ set_interrupt_limits(access);
}
-#endif
+
void StackGuard::Continue(InterruptFlag after_what) {
ExecutionAccess access(isolate_);
@@ -698,78 +642,78 @@ void StackGuard::InitThread(const ExecutionAccess& lock) {
// --- C a l l s t o n a t i v e s ---
-#define RETURN_NATIVE_CALL(name, args, has_pending_exception) \
+#define RETURN_NATIVE_CALL(name, args) \
do { \
Handle<Object> argv[] = args; \
- ASSERT(has_pending_exception != NULL); \
return Call(isolate, \
isolate->name##_fun(), \
isolate->js_builtins_object(), \
- ARRAY_SIZE(argv), argv, \
- has_pending_exception); \
+ ARRAY_SIZE(argv), argv); \
} while (false)
-Handle<Object> Execution::ToNumber(
- Isolate* isolate, Handle<Object> obj, bool* exc) {
- RETURN_NATIVE_CALL(to_number, { obj }, exc);
+MaybeHandle<Object> Execution::ToNumber(
+ Isolate* isolate, Handle<Object> obj) {
+ RETURN_NATIVE_CALL(to_number, { obj });
}
-Handle<Object> Execution::ToString(
- Isolate* isolate, Handle<Object> obj, bool* exc) {
- RETURN_NATIVE_CALL(to_string, { obj }, exc);
+MaybeHandle<Object> Execution::ToString(
+ Isolate* isolate, Handle<Object> obj) {
+ RETURN_NATIVE_CALL(to_string, { obj });
}
-Handle<Object> Execution::ToDetailString(
- Isolate* isolate, Handle<Object> obj, bool* exc) {
- RETURN_NATIVE_CALL(to_detail_string, { obj }, exc);
+MaybeHandle<Object> Execution::ToDetailString(
+ Isolate* isolate, Handle<Object> obj) {
+ RETURN_NATIVE_CALL(to_detail_string, { obj });
}
-Handle<Object> Execution::ToObject(
- Isolate* isolate, Handle<Object> obj, bool* exc) {
+MaybeHandle<Object> Execution::ToObject(
+ Isolate* isolate, Handle<Object> obj) {
if (obj->IsSpecObject()) return obj;
- RETURN_NATIVE_CALL(to_object, { obj }, exc);
+ RETURN_NATIVE_CALL(to_object, { obj });
}
-Handle<Object> Execution::ToInteger(
- Isolate* isolate, Handle<Object> obj, bool* exc) {
- RETURN_NATIVE_CALL(to_integer, { obj }, exc);
+MaybeHandle<Object> Execution::ToInteger(
+ Isolate* isolate, Handle<Object> obj) {
+ RETURN_NATIVE_CALL(to_integer, { obj });
}
-Handle<Object> Execution::ToUint32(
- Isolate* isolate, Handle<Object> obj, bool* exc) {
- RETURN_NATIVE_CALL(to_uint32, { obj }, exc);
+MaybeHandle<Object> Execution::ToUint32(
+ Isolate* isolate, Handle<Object> obj) {
+ RETURN_NATIVE_CALL(to_uint32, { obj });
}
-Handle<Object> Execution::ToInt32(
- Isolate* isolate, Handle<Object> obj, bool* exc) {
- RETURN_NATIVE_CALL(to_int32, { obj }, exc);
+MaybeHandle<Object> Execution::ToInt32(
+ Isolate* isolate, Handle<Object> obj) {
+ RETURN_NATIVE_CALL(to_int32, { obj });
}
-Handle<Object> Execution::NewDate(Isolate* isolate, double time, bool* exc) {
+MaybeHandle<Object> Execution::NewDate(Isolate* isolate, double time) {
Handle<Object> time_obj = isolate->factory()->NewNumber(time);
- RETURN_NATIVE_CALL(create_date, { time_obj }, exc);
+ RETURN_NATIVE_CALL(create_date, { time_obj });
}
#undef RETURN_NATIVE_CALL
-Handle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern,
- Handle<String> flags,
- bool* exc) {
+MaybeHandle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern,
+ Handle<String> flags) {
+ Isolate* isolate = pattern->GetIsolate();
Handle<JSFunction> function = Handle<JSFunction>(
- pattern->GetIsolate()->native_context()->regexp_function());
- Handle<Object> re_obj = RegExpImpl::CreateRegExpLiteral(
- function, pattern, flags, exc);
- if (*exc) return Handle<JSRegExp>();
+ isolate->native_context()->regexp_function());
+ Handle<Object> re_obj;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, re_obj,
+ RegExpImpl::CreateRegExpLiteral(function, pattern, flags),
+ JSRegExp);
return Handle<JSRegExp>::cast(re_obj);
}
@@ -783,97 +727,90 @@ Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) {
return factory->undefined_value();
}
- Handle<Object> char_at = GetProperty(
- isolate, isolate->js_builtins_object(), factory->char_at_string());
+ Handle<Object> char_at = Object::GetProperty(
+ isolate->js_builtins_object(),
+ factory->char_at_string()).ToHandleChecked();
if (!char_at->IsJSFunction()) {
return factory->undefined_value();
}
- bool caught_exception;
Handle<Object> index_object = factory->NewNumberFromInt(int_index);
Handle<Object> index_arg[] = { index_object };
- Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at),
- string,
- ARRAY_SIZE(index_arg),
- index_arg,
- &caught_exception);
- if (caught_exception) {
+ Handle<Object> result;
+ if (!TryCall(Handle<JSFunction>::cast(char_at),
+ string,
+ ARRAY_SIZE(index_arg),
+ index_arg).ToHandle(&result)) {
return factory->undefined_value();
}
return result;
}
-Handle<JSFunction> Execution::InstantiateFunction(
- Handle<FunctionTemplateInfo> data,
- bool* exc) {
+MaybeHandle<JSFunction> Execution::InstantiateFunction(
+ Handle<FunctionTemplateInfo> data) {
Isolate* isolate = data->GetIsolate();
if (!data->do_not_cache()) {
// Fast case: see if the function has already been instantiated
int serial_number = Smi::cast(data->serial_number())->value();
Handle<JSObject> cache(isolate->native_context()->function_cache());
Handle<Object> elm =
- Object::GetElementNoExceptionThrown(isolate, cache, serial_number);
+ Object::GetElement(isolate, cache, serial_number).ToHandleChecked();
if (elm->IsJSFunction()) return Handle<JSFunction>::cast(elm);
}
// The function has not yet been instantiated in this context; do it.
Handle<Object> args[] = { data };
- Handle<Object> result = Call(isolate,
- isolate->instantiate_fun(),
- isolate->js_builtins_object(),
- ARRAY_SIZE(args),
- args,
- exc);
- if (*exc) return Handle<JSFunction>::null();
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ Call(isolate,
+ isolate->instantiate_fun(),
+ isolate->js_builtins_object(),
+ ARRAY_SIZE(args),
+ args),
+ JSFunction);
return Handle<JSFunction>::cast(result);
}
-Handle<JSObject> Execution::InstantiateObject(Handle<ObjectTemplateInfo> data,
- bool* exc) {
+MaybeHandle<JSObject> Execution::InstantiateObject(
+ Handle<ObjectTemplateInfo> data) {
Isolate* isolate = data->GetIsolate();
+ Handle<Object> result;
if (data->property_list()->IsUndefined() &&
!data->constructor()->IsUndefined()) {
- // Initialization to make gcc happy.
- Object* result = NULL;
- {
- HandleScope scope(isolate);
- Handle<FunctionTemplateInfo> cons_template =
- Handle<FunctionTemplateInfo>(
- FunctionTemplateInfo::cast(data->constructor()));
- Handle<JSFunction> cons = InstantiateFunction(cons_template, exc);
- if (*exc) return Handle<JSObject>::null();
- Handle<Object> value = New(cons, 0, NULL, exc);
- if (*exc) return Handle<JSObject>::null();
- result = *value;
- }
- ASSERT(!*exc);
- return Handle<JSObject>(JSObject::cast(result));
+ Handle<FunctionTemplateInfo> cons_template =
+ Handle<FunctionTemplateInfo>(
+ FunctionTemplateInfo::cast(data->constructor()));
+ Handle<JSFunction> cons;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, cons, InstantiateFunction(cons_template), JSObject);
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, result, New(cons, 0, NULL), JSObject);
} else {
Handle<Object> args[] = { data };
- Handle<Object> result = Call(isolate,
- isolate->instantiate_fun(),
- isolate->js_builtins_object(),
- ARRAY_SIZE(args),
- args,
- exc);
- if (*exc) return Handle<JSObject>::null();
- return Handle<JSObject>::cast(result);
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ Call(isolate,
+ isolate->instantiate_fun(),
+ isolate->js_builtins_object(),
+ ARRAY_SIZE(args),
+ args),
+ JSObject);
}
+ return Handle<JSObject>::cast(result);
}
-void Execution::ConfigureInstance(Isolate* isolate,
- Handle<Object> instance,
- Handle<Object> instance_template,
- bool* exc) {
+MaybeHandle<Object> Execution::ConfigureInstance(
+ Isolate* isolate,
+ Handle<Object> instance,
+ Handle<Object> instance_template) {
Handle<Object> args[] = { instance, instance_template };
- Execution::Call(isolate,
- isolate->configure_instance_fun(),
- isolate->js_builtins_object(),
- ARRAY_SIZE(args),
- args,
- exc);
+ return Execution::Call(isolate,
+ isolate->configure_instance_fun(),
+ isolate->js_builtins_object(),
+ ARRAY_SIZE(args),
+ args);
}
@@ -883,14 +820,14 @@ Handle<String> Execution::GetStackTraceLine(Handle<Object> recv,
Handle<Object> is_global) {
Isolate* isolate = fun->GetIsolate();
Handle<Object> args[] = { recv, fun, pos, is_global };
- bool caught_exception;
- Handle<Object> result = TryCall(isolate->get_stack_trace_line_fun(),
- isolate->js_builtins_object(),
- ARRAY_SIZE(args),
- args,
- &caught_exception);
- if (caught_exception || !result->IsString()) {
- return isolate->factory()->empty_string();
+ MaybeHandle<Object> maybe_result =
+ TryCall(isolate->get_stack_trace_line_fun(),
+ isolate->js_builtins_object(),
+ ARRAY_SIZE(args),
+ args);
+ Handle<Object> result;
+ if (!maybe_result.ToHandle(&result) || !result->IsString()) {
+ return isolate->factory()->empty_string();
}
return Handle<String>::cast(result);
@@ -901,7 +838,6 @@ static Object* RuntimePreempt(Isolate* isolate) {
// Clear the preempt request flag.
isolate->stack_guard()->Continue(PREEMPT);
-#ifdef ENABLE_DEBUGGER_SUPPORT
if (isolate->debug()->InDebugger()) {
// If currently in the debugger don't do any actual preemption but record
// that preemption occoured while in the debugger.
@@ -911,19 +847,11 @@ static Object* RuntimePreempt(Isolate* isolate) {
v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
Thread::YieldCPU();
}
-#else
- { // NOLINT
- // Perform preemption.
- v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
- Thread::YieldCPU();
- }
-#endif
return isolate->heap()->undefined_value();
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
Object* Execution::DebugBreakHelper(Isolate* isolate) {
// Just continue if breaks are disabled.
if (isolate->debug()->disable_break()) {
@@ -1001,9 +929,7 @@ void Execution::ProcessDebugMessages(Isolate* isolate,
}
-#endif
-
-MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) {
+Object* Execution::HandleStackGuardInterrupt(Isolate* isolate) {
StackGuard* stack_guard = isolate->stack_guard();
if (stack_guard->ShouldPostponeInterrupts()) {
return isolate->heap()->undefined_value();
@@ -1022,11 +948,9 @@ MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) {
isolate->counters()->stack_interrupts()->Increment();
isolate->counters()->runtime_profiler_ticks()->Increment();
-#ifdef ENABLE_DEBUGGER_SUPPORT
if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) {
DebugBreakHelper(isolate);
}
-#endif
if (stack_guard->IsPreempted()) RuntimePreempt(isolate);
if (stack_guard->IsTerminateExecution()) {
stack_guard->Continue(TERMINATE);
@@ -1053,5 +977,4 @@ MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) {
return isolate->heap()->undefined_value();
}
-
} } // namespace v8::internal
diff --git a/deps/v8/src/execution.h b/deps/v8/src/execution.h
index 592ecbdb62..c165faba0b 100644
--- a/deps/v8/src/execution.h
+++ b/deps/v8/src/execution.h
@@ -1,39 +1,15 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_EXECUTION_H_
#define V8_EXECUTION_H_
-#include "allocation.h"
+#include "handles.h"
namespace v8 {
namespace internal {
-
// Flag used to set the interrupt causes.
enum InterruptFlag {
INTERRUPT = 1 << 0,
@@ -49,10 +25,7 @@ enum InterruptFlag {
};
-class Isolate;
-
-
-class Execution : public AllStatic {
+class Execution V8_FINAL : public AllStatic {
public:
// Call a function, the caller supplies a receiver and an array
// of arguments. Arguments are Object* type. After function returns,
@@ -65,13 +38,13 @@ class Execution : public AllStatic {
// and the function called is not in strict mode, receiver is converted to
// an object.
//
- static Handle<Object> Call(Isolate* isolate,
- Handle<Object> callable,
- Handle<Object> receiver,
- int argc,
- Handle<Object> argv[],
- bool* pending_exception,
- bool convert_receiver = false);
+ MUST_USE_RESULT static MaybeHandle<Object> Call(
+ Isolate* isolate,
+ Handle<Object> callable,
+ Handle<Object> receiver,
+ int argc,
+ Handle<Object> argv[],
+ bool convert_receiver = false);
// Construct object from function, the caller supplies an array of
// arguments. Arguments are Object* type. After function returns,
@@ -80,99 +53,93 @@ class Execution : public AllStatic {
// *pending_exception tells whether the invoke resulted in
// a pending exception.
//
- static Handle<Object> New(Handle<JSFunction> func,
- int argc,
- Handle<Object> argv[],
- bool* pending_exception);
+ MUST_USE_RESULT static MaybeHandle<Object> New(Handle<JSFunction> func,
+ int argc,
+ Handle<Object> argv[]);
// Call a function, just like Call(), but make sure to silently catch
// any thrown exceptions. The return value is either the result of
// calling the function (if caught exception is false) or the exception
// that occurred (if caught exception is true).
- static Handle<Object> TryCall(Handle<JSFunction> func,
- Handle<Object> receiver,
- int argc,
- Handle<Object> argv[],
- bool* caught_exception);
+ static MaybeHandle<Object> TryCall(
+ Handle<JSFunction> func,
+ Handle<Object> receiver,
+ int argc,
+ Handle<Object> argv[],
+ Handle<Object>* exception_out = NULL);
// ECMA-262 9.3
- static Handle<Object> ToNumber(
- Isolate* isolate, Handle<Object> obj, bool* exc);
+ MUST_USE_RESULT static MaybeHandle<Object> ToNumber(
+ Isolate* isolate, Handle<Object> obj);
// ECMA-262 9.4
- static Handle<Object> ToInteger(
- Isolate* isolate, Handle<Object> obj, bool* exc);
+ MUST_USE_RESULT static MaybeHandle<Object> ToInteger(
+ Isolate* isolate, Handle<Object> obj);
// ECMA-262 9.5
- static Handle<Object> ToInt32(
- Isolate* isolate, Handle<Object> obj, bool* exc);
+ MUST_USE_RESULT static MaybeHandle<Object> ToInt32(
+ Isolate* isolate, Handle<Object> obj);
// ECMA-262 9.6
- static Handle<Object> ToUint32(
- Isolate* isolate, Handle<Object> obj, bool* exc);
+ MUST_USE_RESULT static MaybeHandle<Object> ToUint32(
+ Isolate* isolate, Handle<Object> obj);
// ECMA-262 9.8
- static Handle<Object> ToString(
- Isolate* isolate, Handle<Object> obj, bool* exc);
+ MUST_USE_RESULT static MaybeHandle<Object> ToString(
+ Isolate* isolate, Handle<Object> obj);
// ECMA-262 9.8
- static Handle<Object> ToDetailString(
- Isolate* isolate, Handle<Object> obj, bool* exc);
+ MUST_USE_RESULT static MaybeHandle<Object> ToDetailString(
+ Isolate* isolate, Handle<Object> obj);
// ECMA-262 9.9
- static Handle<Object> ToObject(
- Isolate* isolate, Handle<Object> obj, bool* exc);
+ MUST_USE_RESULT static MaybeHandle<Object> ToObject(
+ Isolate* isolate, Handle<Object> obj);
// Create a new date object from 'time'.
- static Handle<Object> NewDate(
- Isolate* isolate, double time, bool* exc);
+ MUST_USE_RESULT static MaybeHandle<Object> NewDate(
+ Isolate* isolate, double time);
// Create a new regular expression object from 'pattern' and 'flags'.
- static Handle<JSRegExp> NewJSRegExp(Handle<String> pattern,
- Handle<String> flags,
- bool* exc);
+ MUST_USE_RESULT static MaybeHandle<JSRegExp> NewJSRegExp(
+ Handle<String> pattern, Handle<String> flags);
// Used to implement [] notation on strings (calls JS code)
static Handle<Object> CharAt(Handle<String> str, uint32_t index);
static Handle<Object> GetFunctionFor();
- static Handle<JSFunction> InstantiateFunction(
- Handle<FunctionTemplateInfo> data, bool* exc);
- static Handle<JSObject> InstantiateObject(Handle<ObjectTemplateInfo> data,
- bool* exc);
- static void ConfigureInstance(Isolate* isolate,
- Handle<Object> instance,
- Handle<Object> data,
- bool* exc);
+ MUST_USE_RESULT static MaybeHandle<JSFunction> InstantiateFunction(
+ Handle<FunctionTemplateInfo> data);
+ MUST_USE_RESULT static MaybeHandle<JSObject> InstantiateObject(
+ Handle<ObjectTemplateInfo> data);
+ MUST_USE_RESULT static MaybeHandle<Object> ConfigureInstance(
+ Isolate* isolate, Handle<Object> instance, Handle<Object> data);
static Handle<String> GetStackTraceLine(Handle<Object> recv,
Handle<JSFunction> fun,
Handle<Object> pos,
Handle<Object> is_global);
-#ifdef ENABLE_DEBUGGER_SUPPORT
+
static Object* DebugBreakHelper(Isolate* isolate);
static void ProcessDebugMessages(Isolate* isolate, bool debug_command_only);
-#endif
// If the stack guard is triggered, but it is not an actual
// stack overflow, then handle the interruption accordingly.
- MUST_USE_RESULT static MaybeObject* HandleStackGuardInterrupt(
- Isolate* isolate);
+ static Object* HandleStackGuardInterrupt(Isolate* isolate);
// Get a function delegate (or undefined) for the given non-function
// object. Used for support calling objects as functions.
static Handle<Object> GetFunctionDelegate(Isolate* isolate,
Handle<Object> object);
- static Handle<Object> TryGetFunctionDelegate(Isolate* isolate,
- Handle<Object> object,
- bool* has_pending_exception);
+ MUST_USE_RESULT static MaybeHandle<Object> TryGetFunctionDelegate(
+ Isolate* isolate,
+ Handle<Object> object);
// Get a function delegate (or undefined) for the given non-function
// object. Used for support calling objects as constructors.
static Handle<Object> GetConstructorDelegate(Isolate* isolate,
Handle<Object> object);
- static Handle<Object> TryGetConstructorDelegate(Isolate* isolate,
- Handle<Object> object,
- bool* has_pending_exception);
+ static MaybeHandle<Object> TryGetConstructorDelegate(Isolate* isolate,
+ Handle<Object> object);
static void RunMicrotasks(Isolate* isolate);
static void EnqueueMicrotask(Isolate* isolate, Handle<Object> microtask);
@@ -185,7 +152,7 @@ class ExecutionAccess;
// StackGuard contains the handling of the limits that are used to limit the
// number of nested invocations of JavaScript and the stack size used in each
// invocation.
-class StackGuard {
+class StackGuard V8_FINAL {
public:
// Pass the address beyond which the stack should not grow. The stack
// is assumed to grow downwards.
@@ -211,12 +178,10 @@ class StackGuard {
bool IsTerminateExecution();
void TerminateExecution();
void CancelTerminateExecution();
-#ifdef ENABLE_DEBUGGER_SUPPORT
bool IsDebugBreak();
void DebugBreak();
bool IsDebugCommand();
void DebugCommand();
-#endif
bool IsGCRequest();
void RequestGC();
bool IsInstallCodeRequest();
@@ -290,7 +255,7 @@ class StackGuard {
static const uintptr_t kIllegalLimit = 0xfffffff8;
#endif
- class ThreadLocal {
+ class ThreadLocal V8_FINAL {
public:
ThreadLocal() { Clear(); }
// You should hold the ExecutionAccess lock when you call Initialize or
@@ -334,7 +299,6 @@ class StackGuard {
DISALLOW_COPY_AND_ASSIGN(StackGuard);
};
-
} } // namespace v8::internal
#endif // V8_EXECUTION_H_
diff --git a/deps/v8/src/extensions/externalize-string-extension.cc b/deps/v8/src/extensions/externalize-string-extension.cc
index adc5577d9e..c942b613ac 100644
--- a/deps/v8/src/extensions/externalize-string-extension.cc
+++ b/deps/v8/src/extensions/externalize-string-extension.cc
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "externalize-string-extension.h"
diff --git a/deps/v8/src/extensions/externalize-string-extension.h b/deps/v8/src/extensions/externalize-string-extension.h
index d0cb5e47d3..305c67dcd6 100644
--- a/deps/v8/src/extensions/externalize-string-extension.h
+++ b/deps/v8/src/extensions/externalize-string-extension.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_EXTENSIONS_EXTERNALIZE_STRING_EXTENSION_H_
#define V8_EXTENSIONS_EXTERNALIZE_STRING_EXTENSION_H_
diff --git a/deps/v8/src/extensions/free-buffer-extension.cc b/deps/v8/src/extensions/free-buffer-extension.cc
index b4abaafe23..4ca0ab5916 100644
--- a/deps/v8/src/extensions/free-buffer-extension.cc
+++ b/deps/v8/src/extensions/free-buffer-extension.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "free-buffer-extension.h"
#include "platform.h"
diff --git a/deps/v8/src/extensions/free-buffer-extension.h b/deps/v8/src/extensions/free-buffer-extension.h
index 26ff7d1bb0..e1fc9fb866 100644
--- a/deps/v8/src/extensions/free-buffer-extension.h
+++ b/deps/v8/src/extensions/free-buffer-extension.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_EXTENSIONS_FREE_BUFFER_EXTENSION_H_
#define V8_EXTENSIONS_FREE_BUFFER_EXTENSION_H_
diff --git a/deps/v8/src/extensions/gc-extension.cc b/deps/v8/src/extensions/gc-extension.cc
index 1d4873de73..5a5884df9d 100644
--- a/deps/v8/src/extensions/gc-extension.cc
+++ b/deps/v8/src/extensions/gc-extension.cc
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "gc-extension.h"
#include "platform.h"
diff --git a/deps/v8/src/extensions/gc-extension.h b/deps/v8/src/extensions/gc-extension.h
index 105c5ad5b7..05f39354a1 100644
--- a/deps/v8/src/extensions/gc-extension.h
+++ b/deps/v8/src/extensions/gc-extension.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_EXTENSIONS_GC_EXTENSION_H_
#define V8_EXTENSIONS_GC_EXTENSION_H_
diff --git a/deps/v8/src/extensions/statistics-extension.cc b/deps/v8/src/extensions/statistics-extension.cc
index e10dddfcdb..a7770e5895 100644
--- a/deps/v8/src/extensions/statistics-extension.cc
+++ b/deps/v8/src/extensions/statistics-extension.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "statistics-extension.h"
diff --git a/deps/v8/src/extensions/statistics-extension.h b/deps/v8/src/extensions/statistics-extension.h
index 9e97b45dd6..7eea82b060 100644
--- a/deps/v8/src/extensions/statistics-extension.h
+++ b/deps/v8/src/extensions/statistics-extension.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_EXTENSIONS_STATISTICS_EXTENSION_H_
#define V8_EXTENSIONS_STATISTICS_EXTENSION_H_
diff --git a/deps/v8/src/extensions/trigger-failure-extension.cc b/deps/v8/src/extensions/trigger-failure-extension.cc
index 83894b922c..31a9818de1 100644
--- a/deps/v8/src/extensions/trigger-failure-extension.cc
+++ b/deps/v8/src/extensions/trigger-failure-extension.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "trigger-failure-extension.h"
#include "v8.h"
diff --git a/deps/v8/src/extensions/trigger-failure-extension.h b/deps/v8/src/extensions/trigger-failure-extension.h
index 467b7d28be..f012b8b583 100644
--- a/deps/v8/src/extensions/trigger-failure-extension.h
+++ b/deps/v8/src/extensions/trigger-failure-extension.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_EXTENSIONS_TRIGGER_FAILURE_EXTENSION_H_
#define V8_EXTENSIONS_TRIGGER_FAILURE_EXTENSION_H_
diff --git a/deps/v8/src/factory.cc b/deps/v8/src/factory.cc
index 0868db851d..9abb015d80 100644
--- a/deps/v8/src/factory.cc
+++ b/deps/v8/src/factory.cc
@@ -1,52 +1,61 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "v8.h"
-
-#include "api.h"
-#include "debug.h"
-#include "execution.h"
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
#include "factory.h"
+
+#include "conversions.h"
#include "isolate-inl.h"
#include "macro-assembler.h"
-#include "objects.h"
-#include "objects-visiting.h"
-#include "platform.h"
-#include "scopeinfo.h"
namespace v8 {
namespace internal {
-Handle<Box> Factory::NewBox(Handle<Object> value, PretenureFlag pretenure) {
+template<typename T>
+Handle<T> Factory::New(Handle<Map> map, AllocationSpace space) {
CALL_HEAP_FUNCTION(
isolate(),
- isolate()->heap()->AllocateBox(*value, pretenure),
- Box);
+ isolate()->heap()->Allocate(*map, space),
+ T);
+}
+
+
+template<typename T>
+Handle<T> Factory::New(Handle<Map> map,
+ AllocationSpace space,
+ Handle<AllocationSite> allocation_site) {
+ CALL_HEAP_FUNCTION(
+ isolate(),
+ isolate()->heap()->Allocate(*map, space, *allocation_site),
+ T);
+}
+
+
+Handle<HeapObject> Factory::NewFillerObject(int size,
+ bool double_align,
+ AllocationSpace space) {
+ CALL_HEAP_FUNCTION(
+ isolate(),
+ isolate()->heap()->AllocateFillerObject(size, double_align, space),
+ HeapObject);
+}
+
+
+Handle<Box> Factory::NewBox(Handle<Object> value) {
+ Handle<Box> result = Handle<Box>::cast(NewStruct(BOX_TYPE));
+ result->set_value(*value);
+ return result;
+}
+
+
+Handle<Oddball> Factory::NewOddball(Handle<Map> map,
+ const char* to_string,
+ Handle<Object> to_number,
+ byte kind) {
+ Handle<Oddball> oddball = New<Oddball>(map, OLD_POINTER_SPACE);
+ Oddball::Initialize(isolate(), oddball, to_string, to_number, kind);
+ return oddball;
}
@@ -64,7 +73,9 @@ Handle<FixedArray> Factory::NewFixedArrayWithHoles(int size,
ASSERT(0 <= size);
CALL_HEAP_FUNCTION(
isolate(),
- isolate()->heap()->AllocateFixedArrayWithHoles(size, pretenure),
+ isolate()->heap()->AllocateFixedArrayWithFiller(size,
+ pretenure,
+ *the_hole_value()),
FixedArray);
}
@@ -77,13 +88,29 @@ Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) {
}
-Handle<FixedDoubleArray> Factory::NewFixedDoubleArray(int size,
- PretenureFlag pretenure) {
+Handle<FixedArrayBase> Factory::NewFixedDoubleArray(int size,
+ PretenureFlag pretenure) {
ASSERT(0 <= size);
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateUninitializedFixedDoubleArray(size, pretenure),
- FixedDoubleArray);
+ FixedArrayBase);
+}
+
+
+Handle<FixedArrayBase> Factory::NewFixedDoubleArrayWithHoles(
+ int size,
+ PretenureFlag pretenure) {
+ ASSERT(0 <= size);
+ Handle<FixedArrayBase> array = NewFixedDoubleArray(size, pretenure);
+ if (size > 0) {
+ Handle<FixedDoubleArray> double_array =
+ Handle<FixedDoubleArray>::cast(array);
+ for (int i = 0; i < size; ++i) {
+ double_array->set_the_hole(i);
+ }
+ }
+ return array;
}
@@ -104,113 +131,31 @@ Handle<ConstantPoolArray> Factory::NewConstantPoolArray(
}
-Handle<NameDictionary> Factory::NewNameDictionary(int at_least_space_for) {
- ASSERT(0 <= at_least_space_for);
- CALL_HEAP_FUNCTION(isolate(),
- NameDictionary::Allocate(isolate()->heap(),
- at_least_space_for),
- NameDictionary);
-}
-
-
-Handle<SeededNumberDictionary> Factory::NewSeededNumberDictionary(
- int at_least_space_for) {
- ASSERT(0 <= at_least_space_for);
- CALL_HEAP_FUNCTION(isolate(),
- SeededNumberDictionary::Allocate(isolate()->heap(),
- at_least_space_for),
- SeededNumberDictionary);
+Handle<OrderedHashSet> Factory::NewOrderedHashSet() {
+ return OrderedHashSet::Allocate(isolate(), 4);
}
-Handle<UnseededNumberDictionary> Factory::NewUnseededNumberDictionary(
- int at_least_space_for) {
- ASSERT(0 <= at_least_space_for);
- CALL_HEAP_FUNCTION(isolate(),
- UnseededNumberDictionary::Allocate(isolate()->heap(),
- at_least_space_for),
- UnseededNumberDictionary);
-}
-
-
-Handle<ObjectHashSet> Factory::NewObjectHashSet(int at_least_space_for) {
- ASSERT(0 <= at_least_space_for);
- CALL_HEAP_FUNCTION(isolate(),
- ObjectHashSet::Allocate(isolate()->heap(),
- at_least_space_for),
- ObjectHashSet);
-}
-
-
-Handle<ObjectHashTable> Factory::NewObjectHashTable(
- int at_least_space_for,
- MinimumCapacity capacity_option) {
- ASSERT(0 <= at_least_space_for);
- CALL_HEAP_FUNCTION(isolate(),
- ObjectHashTable::Allocate(isolate()->heap(),
- at_least_space_for,
- capacity_option),
- ObjectHashTable);
-}
-
-
-Handle<WeakHashTable> Factory::NewWeakHashTable(int at_least_space_for) {
- ASSERT(0 <= at_least_space_for);
- CALL_HEAP_FUNCTION(
- isolate(),
- WeakHashTable::Allocate(isolate()->heap(),
- at_least_space_for,
- USE_DEFAULT_MINIMUM_CAPACITY,
- TENURED),
- WeakHashTable);
-}
-
-
-Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors,
- int slack) {
- ASSERT(0 <= number_of_descriptors);
- CALL_HEAP_FUNCTION(isolate(),
- DescriptorArray::Allocate(
- isolate(), number_of_descriptors, slack),
- DescriptorArray);
-}
-
-
-Handle<DeoptimizationInputData> Factory::NewDeoptimizationInputData(
- int deopt_entry_count,
- PretenureFlag pretenure) {
- ASSERT(deopt_entry_count > 0);
- CALL_HEAP_FUNCTION(isolate(),
- DeoptimizationInputData::Allocate(isolate(),
- deopt_entry_count,
- pretenure),
- DeoptimizationInputData);
-}
-
-
-Handle<DeoptimizationOutputData> Factory::NewDeoptimizationOutputData(
- int deopt_entry_count,
- PretenureFlag pretenure) {
- ASSERT(deopt_entry_count > 0);
- CALL_HEAP_FUNCTION(isolate(),
- DeoptimizationOutputData::Allocate(isolate(),
- deopt_entry_count,
- pretenure),
- DeoptimizationOutputData);
+Handle<OrderedHashMap> Factory::NewOrderedHashMap() {
+ return OrderedHashMap::Allocate(isolate(), 4);
}
Handle<AccessorPair> Factory::NewAccessorPair() {
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->AllocateAccessorPair(),
- AccessorPair);
+ Handle<AccessorPair> accessors =
+ Handle<AccessorPair>::cast(NewStruct(ACCESSOR_PAIR_TYPE));
+ accessors->set_getter(*the_hole_value(), SKIP_WRITE_BARRIER);
+ accessors->set_setter(*the_hole_value(), SKIP_WRITE_BARRIER);
+ accessors->set_access_flags(Smi::FromInt(0), SKIP_WRITE_BARRIER);
+ return accessors;
}
Handle<TypeFeedbackInfo> Factory::NewTypeFeedbackInfo() {
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->AllocateTypeFeedbackInfo(),
- TypeFeedbackInfo);
+ Handle<TypeFeedbackInfo> info =
+ Handle<TypeFeedbackInfo>::cast(NewStruct(TYPE_FEEDBACK_INFO_TYPE));
+ info->initialize_storage();
+ return info;
}
@@ -223,9 +168,8 @@ Handle<String> Factory::InternalizeUtf8String(Vector<const char> string) {
// Internalized strings are created in the old generation (data space).
Handle<String> Factory::InternalizeString(Handle<String> string) {
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->InternalizeString(*string),
- String);
+ if (string->IsInternalizedString()) return string;
+ return StringTable::LookupString(isolate(), string);
}
@@ -250,9 +194,7 @@ Handle<String> Factory::InternalizeTwoByteString(Vector<const uc16> string) {
template<class StringTableKey>
Handle<String> Factory::InternalizeStringWithKey(StringTableKey* key) {
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->InternalizeStringWithKey(key),
- String);
+ return StringTable::LookupKey(isolate(), key);
}
@@ -262,25 +204,50 @@ template Handle<String> Factory::InternalizeStringWithKey<
SubStringKey<uint16_t> > (SubStringKey<uint16_t>* key);
-Handle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string,
- PretenureFlag pretenure) {
- CALL_HEAP_FUNCTION(
+MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string,
+ PretenureFlag pretenure) {
+ int length = string.length();
+ if (length == 1) {
+ return LookupSingleCharacterStringFromCode(string[0]);
+ }
+ Handle<SeqOneByteString> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
isolate(),
- isolate()->heap()->AllocateStringFromOneByte(string, pretenure),
+ result,
+ NewRawOneByteString(string.length(), pretenure),
String);
+
+ DisallowHeapAllocation no_gc;
+ // Copy the characters into the new object.
+ CopyChars(SeqOneByteString::cast(*result)->GetChars(),
+ string.start(),
+ length);
+ return result;
}
-Handle<String> Factory::NewStringFromUtf8(Vector<const char> string,
- PretenureFlag pretenure) {
+MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string,
+ PretenureFlag pretenure) {
+ // Check for ASCII first since this is the common case.
+ const char* start = string.start();
+ int length = string.length();
+ int non_ascii_start = String::NonAsciiStart(start, length);
+ if (non_ascii_start >= length) {
+ // If the string is ASCII, we do not need to convert the characters
+ // since UTF8 is backwards compatible with ASCII.
+ return NewStringFromOneByte(Vector<const uint8_t>::cast(string), pretenure);
+ }
+ // Non-ASCII and we need to decode.
CALL_HEAP_FUNCTION(
isolate(),
- isolate()->heap()->AllocateStringFromUtf8(string, pretenure),
+ isolate()->heap()->AllocateStringFromUtf8Slow(string,
+ non_ascii_start,
+ pretenure),
String);
}
-Handle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string,
- PretenureFlag pretenure) {
+MaybeHandle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string,
+ PretenureFlag pretenure) {
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateStringFromTwoByte(string, pretenure),
@@ -288,8 +255,74 @@ Handle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string,
}
-Handle<SeqOneByteString> Factory::NewRawOneByteString(int length,
- PretenureFlag pretenure) {
+Handle<String> Factory::NewInternalizedStringFromUtf8(Vector<const char> str,
+ int chars,
+ uint32_t hash_field) {
+ CALL_HEAP_FUNCTION(
+ isolate(),
+ isolate()->heap()->AllocateInternalizedStringFromUtf8(
+ str, chars, hash_field),
+ String);
+}
+
+
+MUST_USE_RESULT Handle<String> Factory::NewOneByteInternalizedString(
+ Vector<const uint8_t> str,
+ uint32_t hash_field) {
+ CALL_HEAP_FUNCTION(
+ isolate(),
+ isolate()->heap()->AllocateOneByteInternalizedString(str, hash_field),
+ String);
+}
+
+
+MUST_USE_RESULT Handle<String> Factory::NewTwoByteInternalizedString(
+ Vector<const uc16> str,
+ uint32_t hash_field) {
+ CALL_HEAP_FUNCTION(
+ isolate(),
+ isolate()->heap()->AllocateTwoByteInternalizedString(str, hash_field),
+ String);
+}
+
+
+Handle<String> Factory::NewInternalizedStringImpl(
+ Handle<String> string, int chars, uint32_t hash_field) {
+ CALL_HEAP_FUNCTION(
+ isolate(),
+ isolate()->heap()->AllocateInternalizedStringImpl(
+ *string, chars, hash_field),
+ String);
+}
+
+
+MaybeHandle<Map> Factory::InternalizedStringMapForString(
+ Handle<String> string) {
+ // If the string is in new space it cannot be used as internalized.
+ if (isolate()->heap()->InNewSpace(*string)) return MaybeHandle<Map>();
+
+ // Find the corresponding internalized string map for strings.
+ switch (string->map()->instance_type()) {
+ case STRING_TYPE: return internalized_string_map();
+ case ASCII_STRING_TYPE: return ascii_internalized_string_map();
+ case EXTERNAL_STRING_TYPE: return external_internalized_string_map();
+ case EXTERNAL_ASCII_STRING_TYPE:
+ return external_ascii_internalized_string_map();
+ case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
+ return external_internalized_string_with_one_byte_data_map();
+ case SHORT_EXTERNAL_STRING_TYPE:
+ return short_external_internalized_string_map();
+ case SHORT_EXTERNAL_ASCII_STRING_TYPE:
+ return short_external_ascii_internalized_string_map();
+ case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
+ return short_external_internalized_string_with_one_byte_data_map();
+ default: return MaybeHandle<Map>(); // No match found.
+ }
+}
+
+
+MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString(
+ int length, PretenureFlag pretenure) {
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateRawOneByteString(length, pretenure),
@@ -297,8 +330,8 @@ Handle<SeqOneByteString> Factory::NewRawOneByteString(int length,
}
-Handle<SeqTwoByteString> Factory::NewRawTwoByteString(int length,
- PretenureFlag pretenure) {
+MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString(
+ int length, PretenureFlag pretenure) {
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateRawTwoByteString(length, pretenure),
@@ -306,6 +339,30 @@ Handle<SeqTwoByteString> Factory::NewRawTwoByteString(int length,
}
+Handle<String> Factory::LookupSingleCharacterStringFromCode(uint32_t code) {
+ if (code <= String::kMaxOneByteCharCodeU) {
+ {
+ DisallowHeapAllocation no_allocation;
+ Object* value = single_character_string_cache()->get(code);
+ if (value != *undefined_value()) {
+ return handle(String::cast(value), isolate());
+ }
+ }
+ uint8_t buffer[1];
+ buffer[0] = static_cast<uint8_t>(code);
+ Handle<String> result =
+ InternalizeOneByteString(Vector<const uint8_t>(buffer, 1));
+ single_character_string_cache()->set(code, *result);
+ return result;
+ }
+ ASSERT(code <= String::kMaxUtf16CodeUnitU);
+
+ Handle<SeqTwoByteString> result = NewRawTwoByteString(1).ToHandleChecked();
+ result->SeqTwoByteStringSet(0, static_cast<uint16_t>(code));
+ return result;
+}
+
+
// Returns true for a character in a range. Both limits are inclusive.
static inline bool Between(uint32_t character, uint32_t from, uint32_t to) {
// This makes uses of the the unsigned wraparound.
@@ -319,10 +376,10 @@ static inline Handle<String> MakeOrFindTwoCharacterString(Isolate* isolate,
// Numeric strings have a different hash algorithm not known by
// LookupTwoCharsStringIfExists, so we skip this step for such strings.
if (!Between(c1, '0', '9') || !Between(c2, '0', '9')) {
- String* result;
- StringTable* table = isolate->heap()->string_table();
- if (table->LookupTwoCharsStringIfExists(c1, c2, &result)) {
- return handle(result);
+ Handle<String> result;
+ if (StringTable::LookupTwoCharsStringIfExists(isolate, c1, c2).
+ ToHandle(&result)) {
+ return result;
}
}
@@ -331,13 +388,15 @@ static inline Handle<String> MakeOrFindTwoCharacterString(Isolate* isolate,
if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) {
// We can do this.
ASSERT(IsPowerOf2(String::kMaxOneByteCharCodeU + 1)); // because of this.
- Handle<SeqOneByteString> str = isolate->factory()->NewRawOneByteString(2);
+ Handle<SeqOneByteString> str =
+ isolate->factory()->NewRawOneByteString(2).ToHandleChecked();
uint8_t* dest = str->GetChars();
dest[0] = static_cast<uint8_t>(c1);
dest[1] = static_cast<uint8_t>(c2);
return str;
} else {
- Handle<SeqTwoByteString> str = isolate->factory()->NewRawTwoByteString(2);
+ Handle<SeqTwoByteString> str =
+ isolate->factory()->NewRawTwoByteString(2).ToHandleChecked();
uc16* dest = str->GetChars();
dest[0] = c1;
dest[1] = c2;
@@ -358,17 +417,8 @@ Handle<String> ConcatStringContent(Handle<StringType> result,
}
-Handle<ConsString> Factory::NewRawConsString(String::Encoding encoding) {
- Handle<Map> map = (encoding == String::ONE_BYTE_ENCODING)
- ? cons_ascii_string_map() : cons_string_map();
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->Allocate(*map, NEW_SPACE),
- ConsString);
-}
-
-
-Handle<String> Factory::NewConsString(Handle<String> left,
- Handle<String> right) {
+MaybeHandle<String> Factory::NewConsString(Handle<String> left,
+ Handle<String> right) {
int left_length = left->length();
if (left_length == 0) return right;
int right_length = right->length();
@@ -385,8 +435,7 @@ Handle<String> Factory::NewConsString(Handle<String> left,
// Make sure that an out of memory exception is thrown if the length
// of the new cons string is too large.
if (length > String::kMaxLength || length < 0) {
- isolate()->ThrowInvalidStringLength();
- return Handle<String>::null();
+ return isolate()->Throw<String>(NewInvalidStringLengthError());
}
bool left_is_one_byte = left->IsOneByteRepresentation();
@@ -413,7 +462,8 @@ Handle<String> Factory::NewConsString(Handle<String> left,
STATIC_ASSERT(ConsString::kMinLength <= String::kMaxLength);
if (is_one_byte) {
- Handle<SeqOneByteString> result = NewRawOneByteString(length);
+ Handle<SeqOneByteString> result =
+ NewRawOneByteString(length).ToHandleChecked();
DisallowHeapAllocation no_gc;
uint8_t* dest = result->GetChars();
// Copy left part.
@@ -430,14 +480,15 @@ Handle<String> Factory::NewConsString(Handle<String> left,
}
return (is_one_byte_data_in_two_byte_string)
- ? ConcatStringContent<uint8_t>(NewRawOneByteString(length), left, right)
- : ConcatStringContent<uc16>(NewRawTwoByteString(length), left, right);
+ ? ConcatStringContent<uint8_t>(
+ NewRawOneByteString(length).ToHandleChecked(), left, right)
+ : ConcatStringContent<uc16>(
+ NewRawTwoByteString(length).ToHandleChecked(), left, right);
}
- Handle<ConsString> result = NewRawConsString(
- (is_one_byte || is_one_byte_data_in_two_byte_string)
- ? String::ONE_BYTE_ENCODING
- : String::TWO_BYTE_ENCODING);
+ Handle<Map> map = (is_one_byte || is_one_byte_data_in_two_byte_string)
+ ? cons_ascii_string_map() : cons_string_map();
+ Handle<ConsString> result = New<ConsString>(map, NEW_SPACE);
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
@@ -455,23 +506,14 @@ Handle<String> Factory::NewFlatConcatString(Handle<String> first,
int total_length = first->length() + second->length();
if (first->IsOneByteRepresentation() && second->IsOneByteRepresentation()) {
return ConcatStringContent<uint8_t>(
- NewRawOneByteString(total_length), first, second);
+ NewRawOneByteString(total_length).ToHandleChecked(), first, second);
} else {
return ConcatStringContent<uc16>(
- NewRawTwoByteString(total_length), first, second);
+ NewRawTwoByteString(total_length).ToHandleChecked(), first, second);
}
}
-Handle<SlicedString> Factory::NewRawSlicedString(String::Encoding encoding) {
- Handle<Map> map = (encoding == String::ONE_BYTE_ENCODING)
- ? sliced_ascii_string_map() : sliced_string_map();
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->Allocate(*map, NEW_SPACE),
- SlicedString);
-}
-
-
Handle<String> Factory::NewProperSubString(Handle<String> str,
int begin,
int end) {
@@ -480,10 +522,12 @@ Handle<String> Factory::NewProperSubString(Handle<String> str,
#endif
ASSERT(begin > 0 || end < str->length());
+ str = String::Flatten(str);
+
int length = end - begin;
if (length <= 0) return empty_string();
if (length == 1) {
- return LookupSingleCharacterStringFromCode(isolate(), str->Get(begin));
+ return LookupSingleCharacterStringFromCode(str->Get(begin));
}
if (length == 2) {
// Optimization for 2-byte strings often used as keys in a decompression
@@ -496,15 +540,15 @@ Handle<String> Factory::NewProperSubString(Handle<String> str,
if (!FLAG_string_slices || length < SlicedString::kMinLength) {
if (str->IsOneByteRepresentation()) {
- Handle<SeqOneByteString> result = NewRawOneByteString(length);
- ASSERT(!result.is_null());
+ Handle<SeqOneByteString> result =
+ NewRawOneByteString(length).ToHandleChecked();
uint8_t* dest = result->GetChars();
DisallowHeapAllocation no_gc;
String::WriteToFlat(*str, dest, begin, end);
return result;
} else {
- Handle<SeqTwoByteString> result = NewRawTwoByteString(length);
- ASSERT(!result.is_null());
+ Handle<SeqTwoByteString> result =
+ NewRawTwoByteString(length).ToHandleChecked();
uc16* dest = result->GetChars();
DisallowHeapAllocation no_gc;
String::WriteToFlat(*str, dest, begin, end);
@@ -514,34 +558,16 @@ Handle<String> Factory::NewProperSubString(Handle<String> str,
int offset = begin;
- while (str->IsConsString()) {
- Handle<ConsString> cons = Handle<ConsString>::cast(str);
- int split = cons->first()->length();
- if (split <= offset) {
- // Slice is fully contained in the second part.
- str = Handle<String>(cons->second(), isolate());
- offset -= split; // Adjust for offset.
- continue;
- } else if (offset + length <= split) {
- // Slice is fully contained in the first part.
- str = Handle<String>(cons->first(), isolate());
- continue;
- }
- break;
- }
-
if (str->IsSlicedString()) {
Handle<SlicedString> slice = Handle<SlicedString>::cast(str);
str = Handle<String>(slice->parent(), isolate());
offset += slice->offset();
- } else {
- str = FlattenGetString(str);
}
ASSERT(str->IsSeqString() || str->IsExternalString());
- Handle<SlicedString> slice = NewRawSlicedString(
- str->IsOneByteRepresentation() ? String::ONE_BYTE_ENCODING
- : String::TWO_BYTE_ENCODING);
+ Handle<Map> map = str->IsOneByteRepresentation() ? sliced_ascii_string_map()
+ : sliced_string_map();
+ Handle<SlicedString> slice = New<SlicedString>(map, NEW_SPACE);
slice->set_hash_field(String::kEmptyHashField);
slice->set_length(length);
@@ -551,21 +577,47 @@ Handle<String> Factory::NewProperSubString(Handle<String> str,
}
-Handle<String> Factory::NewExternalStringFromAscii(
+MaybeHandle<String> Factory::NewExternalStringFromAscii(
const ExternalAsciiString::Resource* resource) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateExternalStringFromAscii(resource),
- String);
+ size_t length = resource->length();
+ if (length > static_cast<size_t>(String::kMaxLength)) {
+ isolate()->ThrowInvalidStringLength();
+ return MaybeHandle<String>();
+ }
+
+ Handle<Map> map = external_ascii_string_map();
+ Handle<ExternalAsciiString> external_string =
+ New<ExternalAsciiString>(map, NEW_SPACE);
+ external_string->set_length(static_cast<int>(length));
+ external_string->set_hash_field(String::kEmptyHashField);
+ external_string->set_resource(resource);
+
+ return external_string;
}
-Handle<String> Factory::NewExternalStringFromTwoByte(
+MaybeHandle<String> Factory::NewExternalStringFromTwoByte(
const ExternalTwoByteString::Resource* resource) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateExternalStringFromTwoByte(resource),
- String);
+ size_t length = resource->length();
+ if (length > static_cast<size_t>(String::kMaxLength)) {
+ isolate()->ThrowInvalidStringLength();
+ return MaybeHandle<String>();
+ }
+
+ // For small strings we check whether the resource contains only
+ // one byte characters. If yes, we use a different string map.
+ static const size_t kOneByteCheckLengthLimit = 32;
+ bool is_one_byte = length <= kOneByteCheckLengthLimit &&
+ String::IsOneByte(resource->data(), static_cast<int>(length));
+ Handle<Map> map = is_one_byte ?
+ external_string_with_one_byte_data_map() : external_string_map();
+ Handle<ExternalTwoByteString> external_string =
+ New<ExternalTwoByteString>(map, NEW_SPACE);
+ external_string->set_length(static_cast<int>(length));
+ external_string->set_hash_field(String::kEmptyHashField);
+ external_string->set_resource(resource);
+
+ return external_string;
}
@@ -578,44 +630,59 @@ Handle<Symbol> Factory::NewSymbol() {
Handle<Symbol> Factory::NewPrivateSymbol() {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocatePrivateSymbol(),
- Symbol);
+ Handle<Symbol> symbol = NewSymbol();
+ symbol->set_is_private(true);
+ return symbol;
}
Handle<Context> Factory::NewNativeContext() {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateNativeContext(),
- Context);
+ Handle<FixedArray> array = NewFixedArray(Context::NATIVE_CONTEXT_SLOTS);
+ array->set_map_no_write_barrier(*native_context_map());
+ Handle<Context> context = Handle<Context>::cast(array);
+ context->set_js_array_maps(*undefined_value());
+ ASSERT(context->IsNativeContext());
+ return context;
}
Handle<Context> Factory::NewGlobalContext(Handle<JSFunction> function,
Handle<ScopeInfo> scope_info) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateGlobalContext(*function, *scope_info),
- Context);
+ Handle<FixedArray> array =
+ NewFixedArray(scope_info->ContextLength(), TENURED);
+ array->set_map_no_write_barrier(*global_context_map());
+ Handle<Context> context = Handle<Context>::cast(array);
+ context->set_closure(*function);
+ context->set_previous(function->context());
+ context->set_extension(*scope_info);
+ context->set_global_object(function->context()->global_object());
+ ASSERT(context->IsGlobalContext());
+ return context;
}
Handle<Context> Factory::NewModuleContext(Handle<ScopeInfo> scope_info) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateModuleContext(*scope_info),
- Context);
+ Handle<FixedArray> array =
+ NewFixedArray(scope_info->ContextLength(), TENURED);
+ array->set_map_no_write_barrier(*module_context_map());
+ // Instance link will be set later.
+ Handle<Context> context = Handle<Context>::cast(array);
+ context->set_extension(Smi::FromInt(0));
+ return context;
}
Handle<Context> Factory::NewFunctionContext(int length,
Handle<JSFunction> function) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateFunctionContext(length, *function),
- Context);
+ ASSERT(length >= Context::MIN_CONTEXT_SLOTS);
+ Handle<FixedArray> array = NewFixedArray(length);
+ array->set_map_no_write_barrier(*function_context_map());
+ Handle<Context> context = Handle<Context>::cast(array);
+ context->set_closure(*function);
+ context->set_previous(function->context());
+ context->set_extension(Smi::FromInt(0));
+ context->set_global_object(function->context()->global_object());
+ return context;
}
@@ -623,35 +690,45 @@ Handle<Context> Factory::NewCatchContext(Handle<JSFunction> function,
Handle<Context> previous,
Handle<String> name,
Handle<Object> thrown_object) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateCatchContext(*function,
- *previous,
- *name,
- *thrown_object),
- Context);
+ STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == Context::THROWN_OBJECT_INDEX);
+ Handle<FixedArray> array = NewFixedArray(Context::MIN_CONTEXT_SLOTS + 1);
+ array->set_map_no_write_barrier(*catch_context_map());
+ Handle<Context> context = Handle<Context>::cast(array);
+ context->set_closure(*function);
+ context->set_previous(*previous);
+ context->set_extension(*name);
+ context->set_global_object(previous->global_object());
+ context->set(Context::THROWN_OBJECT_INDEX, *thrown_object);
+ return context;
}
Handle<Context> Factory::NewWithContext(Handle<JSFunction> function,
Handle<Context> previous,
- Handle<JSObject> extension) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateWithContext(*function, *previous, *extension),
- Context);
+ Handle<JSReceiver> extension) {
+ Handle<FixedArray> array = NewFixedArray(Context::MIN_CONTEXT_SLOTS);
+ array->set_map_no_write_barrier(*with_context_map());
+ Handle<Context> context = Handle<Context>::cast(array);
+ context->set_closure(*function);
+ context->set_previous(*previous);
+ context->set_extension(*extension);
+ context->set_global_object(previous->global_object());
+ return context;
}
Handle<Context> Factory::NewBlockContext(Handle<JSFunction> function,
Handle<Context> previous,
Handle<ScopeInfo> scope_info) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateBlockContext(*function,
- *previous,
- *scope_info),
- Context);
+ Handle<FixedArray> array =
+ NewFixedArrayWithHoles(scope_info->ContextLength());
+ array->set_map_no_write_barrier(*block_context_map());
+ Handle<Context> context = Handle<Context>::cast(array);
+ context->set_closure(*function);
+ context->set_previous(*previous);
+ context->set_extension(*scope_info);
+ context->set_global_object(previous->global_object());
+ return context;
}
@@ -663,6 +740,15 @@ Handle<Struct> Factory::NewStruct(InstanceType type) {
}
+Handle<CodeCache> Factory::NewCodeCache() {
+ Handle<CodeCache> code_cache =
+ Handle<CodeCache>::cast(NewStruct(CODE_CACHE_TYPE));
+ code_cache->set_default_cache(*empty_fixed_array(), SKIP_WRITE_BARRIER);
+ code_cache->set_normal_type_cache(*undefined_value(), SKIP_WRITE_BARRIER);
+ return code_cache;
+}
+
+
Handle<AliasedArgumentsEntry> Factory::NewAliasedArgumentsEntry(
int aliased_context_slot) {
Handle<AliasedArgumentsEntry> entry = Handle<AliasedArgumentsEntry>::cast(
@@ -799,10 +885,14 @@ Handle<PropertyCell> Factory::NewPropertyCell(Handle<Object> value) {
Handle<AllocationSite> Factory::NewAllocationSite() {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateAllocationSite(),
- AllocationSite);
+ Handle<Map> map = allocation_site_map();
+ Handle<AllocationSite> site = New<AllocationSite>(map, OLD_POINTER_SPACE);
+ site->Initialize();
+
+ // Link the site
+ site->set_weak_next(isolate()->heap()->allocation_sites_list());
+ isolate()->heap()->set_allocation_sites_list(*site);
+ return site;
}
@@ -816,75 +906,36 @@ Handle<Map> Factory::NewMap(InstanceType type,
}
-Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
- // Make sure to use globals from the function's context, since the function
- // can be from a different context.
- Handle<Context> native_context(function->context()->native_context());
- Handle<Map> new_map;
- if (function->shared()->is_generator()) {
- // Generator prototypes can share maps since they don't have "constructor"
- // properties.
- new_map = handle(native_context->generator_object_prototype_map());
- } else {
- // Each function prototype gets a fresh map to avoid unwanted sharing of
- // maps between prototypes of different constructors.
- Handle<JSFunction> object_function(native_context->object_function());
- ASSERT(object_function->has_initial_map());
- new_map = Map::Copy(handle(object_function->initial_map()));
- }
-
- Handle<JSObject> prototype = NewJSObjectFromMap(new_map);
-
- if (!function->shared()->is_generator()) {
- JSObject::SetLocalPropertyIgnoreAttributes(prototype,
- constructor_string(),
- function,
- DONT_ENUM);
- }
-
- return prototype;
-}
-
-
-Handle<Map> Factory::CopyWithPreallocatedFieldDescriptors(Handle<Map> src) {
- CALL_HEAP_FUNCTION(
- isolate(), src->CopyWithPreallocatedFieldDescriptors(), Map);
+Handle<JSObject> Factory::CopyJSObject(Handle<JSObject> object) {
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->CopyJSObject(*object, NULL),
+ JSObject);
}
-Handle<Map> Factory::CopyMap(Handle<Map> src,
- int extra_inobject_properties) {
- Handle<Map> copy = CopyWithPreallocatedFieldDescriptors(src);
- // Check that we do not overflow the instance size when adding the
- // extra inobject properties.
- int instance_size_delta = extra_inobject_properties * kPointerSize;
- int max_instance_size_delta =
- JSObject::kMaxInstanceSize - copy->instance_size();
- int max_extra_properties = max_instance_size_delta >> kPointerSizeLog2;
- if (extra_inobject_properties > max_extra_properties) {
- // If the instance size overflows, we allocate as many properties
- // as we can as inobject properties.
- instance_size_delta = max_instance_size_delta;
- extra_inobject_properties = max_extra_properties;
- }
- // Adjust the map with the extra inobject properties.
- int inobject_properties =
- copy->inobject_properties() + extra_inobject_properties;
- copy->set_inobject_properties(inobject_properties);
- copy->set_unused_property_fields(inobject_properties);
- copy->set_instance_size(copy->instance_size() + instance_size_delta);
- copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy));
- return copy;
+Handle<JSObject> Factory::CopyJSObjectWithAllocationSite(
+ Handle<JSObject> object,
+ Handle<AllocationSite> site) {
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->CopyJSObject(
+ *object,
+ site.is_null() ? NULL : *site),
+ JSObject);
}
-Handle<Map> Factory::CopyMap(Handle<Map> src) {
- CALL_HEAP_FUNCTION(isolate(), src->Copy(), Map);
+Handle<FixedArray> Factory::CopyFixedArrayWithMap(Handle<FixedArray> array,
+ Handle<Map> map) {
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->CopyFixedArrayWithMap(*array, *map),
+ FixedArray);
}
Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) {
- CALL_HEAP_FUNCTION(isolate(), array->Copy(), FixedArray);
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->CopyFixedArray(*array),
+ FixedArray);
}
@@ -897,125 +948,54 @@ Handle<FixedArray> Factory::CopyAndTenureFixedCOWArray(
}
-Handle<FixedArray> Factory::CopySizeFixedArray(Handle<FixedArray> array,
- int new_length,
- PretenureFlag pretenure) {
- CALL_HEAP_FUNCTION(isolate(),
- array->CopySize(new_length, pretenure),
- FixedArray);
-}
-
-
Handle<FixedDoubleArray> Factory::CopyFixedDoubleArray(
Handle<FixedDoubleArray> array) {
- CALL_HEAP_FUNCTION(isolate(), array->Copy(), FixedDoubleArray);
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->CopyFixedDoubleArray(*array),
+ FixedDoubleArray);
}
Handle<ConstantPoolArray> Factory::CopyConstantPoolArray(
Handle<ConstantPoolArray> array) {
- CALL_HEAP_FUNCTION(isolate(), array->Copy(), ConstantPoolArray);
-}
-
-
-Handle<JSFunction> Factory::BaseNewFunctionFromSharedFunctionInfo(
- Handle<SharedFunctionInfo> function_info,
- Handle<Map> function_map,
- PretenureFlag pretenure) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateFunction(*function_map,
- *function_info,
- isolate()->heap()->the_hole_value(),
- pretenure),
- JSFunction);
-}
-
-
-static Handle<Map> MapForNewFunction(Isolate *isolate,
- Handle<SharedFunctionInfo> function_info) {
- Context *context = isolate->context()->native_context();
- int map_index = Context::FunctionMapIndex(function_info->strict_mode(),
- function_info->is_generator());
- return Handle<Map>(Map::cast(context->get(map_index)));
-}
-
-
-Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
- Handle<SharedFunctionInfo> function_info,
- Handle<Context> context,
- PretenureFlag pretenure) {
- Handle<JSFunction> result = BaseNewFunctionFromSharedFunctionInfo(
- function_info,
- MapForNewFunction(isolate(), function_info),
- pretenure);
-
- if (function_info->ic_age() != isolate()->heap()->global_ic_age()) {
- function_info->ResetForNewContext(isolate()->heap()->global_ic_age());
- }
-
- result->set_context(*context);
-
- int index = function_info->SearchOptimizedCodeMap(context->native_context(),
- BailoutId::None());
- if (!function_info->bound() && index < 0) {
- int number_of_literals = function_info->num_literals();
- Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure);
- if (number_of_literals > 0) {
- // Store the native context in the literals array prefix. This
- // context will be used when creating object, regexp and array
- // literals in this function.
- literals->set(JSFunction::kLiteralNativeContextIndex,
- context->native_context());
- }
- result->set_literals(*literals);
- }
-
- if (index > 0) {
- // Caching of optimized code enabled and optimized code found.
- FixedArray* literals =
- function_info->GetLiteralsFromOptimizedCodeMap(index);
- if (literals != NULL) result->set_literals(literals);
- Code* code = function_info->GetCodeFromOptimizedCodeMap(index);
- ASSERT(!code->marked_for_deoptimization());
- result->ReplaceCode(code);
- return result;
- }
-
- if (isolate()->use_crankshaft() &&
- FLAG_always_opt &&
- result->is_compiled() &&
- !function_info->is_toplevel() &&
- function_info->allows_lazy_compilation() &&
- !function_info->optimization_disabled() &&
- !isolate()->DebuggerHasBreakPoints()) {
- result->MarkForOptimization();
- }
- return result;
+ CALL_HEAP_FUNCTION(isolate(),
+ isolate()->heap()->CopyConstantPoolArray(*array),
+ ConstantPoolArray);
}
Handle<Object> Factory::NewNumber(double value,
PretenureFlag pretenure) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->NumberFromDouble(value, pretenure), Object);
+ // We need to distinguish the minus zero value and this cannot be
+ // done after conversion to int. Doing this by comparing bit
+ // patterns is faster than using fpclassify() et al.
+ if (IsMinusZero(value)) return NewHeapNumber(-0.0, pretenure);
+
+ int int_value = FastD2I(value);
+ if (value == int_value && Smi::IsValid(int_value)) {
+ return handle(Smi::FromInt(int_value), isolate());
+ }
+
+ // Materialize the value in the heap.
+ return NewHeapNumber(value, pretenure);
}
Handle<Object> Factory::NewNumberFromInt(int32_t value,
PretenureFlag pretenure) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->NumberFromInt32(value, pretenure), Object);
+ if (Smi::IsValid(value)) return handle(Smi::FromInt(value), isolate());
+ // Bypass NumberFromDouble to avoid various redundant checks.
+ return NewHeapNumber(FastI2D(value), pretenure);
}
Handle<Object> Factory::NewNumberFromUint(uint32_t value,
- PretenureFlag pretenure) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->NumberFromUint32(value, pretenure), Object);
+ PretenureFlag pretenure) {
+ int32_t int32v = static_cast<int32_t>(value);
+ if (int32v >= 0 && Smi::IsValid(int32v)) {
+ return handle(Smi::FromInt(int32v), isolate());
+ }
+ return NewHeapNumber(FastUI2D(value), pretenure);
}
@@ -1027,15 +1007,6 @@ Handle<HeapNumber> Factory::NewHeapNumber(double value,
}
-Handle<JSObject> Factory::NewNeanderObject() {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateJSObjectFromMap(
- isolate()->heap()->neander_map()),
- JSObject);
-}
-
-
Handle<Object> Factory::NewTypeError(const char* message,
Vector< Handle<Object> > args) {
return NewError("MakeTypeError", message, args);
@@ -1131,7 +1102,7 @@ Handle<String> Factory::EmergencyNewError(const char* message,
space--;
if (space > 0) {
Handle<String> arg_str = Handle<String>::cast(
- Object::GetElementNoExceptionThrown(isolate(), args, i));
+ Object::GetElement(isolate(), args, i).ToHandleChecked());
SmartArrayPointer<char> arg = arg_str->ToCString();
Vector<char> v2(p, static_cast<int>(space));
OS::StrNCpy(v2, arg.get(), space);
@@ -1145,8 +1116,7 @@ Handle<String> Factory::EmergencyNewError(const char* message,
} else {
buffer[kBufferSize - 1] = '\0';
}
- Handle<String> error_string = NewStringFromUtf8(CStrVector(buffer), TENURED);
- return error_string;
+ return NewStringFromUtf8(CStrVector(buffer), TENURED).ToHandleChecked();
}
@@ -1154,9 +1124,8 @@ Handle<Object> Factory::NewError(const char* maker,
const char* message,
Handle<JSArray> args) {
Handle<String> make_str = InternalizeUtf8String(maker);
- Handle<Object> fun_obj(
- isolate()->js_builtins_object()->GetPropertyNoExceptionThrown(*make_str),
- isolate());
+ Handle<Object> fun_obj = Object::GetProperty(
+ isolate()->js_builtins_object(), make_str).ToHandleChecked();
// If the builtins haven't been properly configured yet this error
// constructor may not have been defined. Bail out.
if (!fun_obj->IsJSFunction()) {
@@ -1168,12 +1137,15 @@ Handle<Object> Factory::NewError(const char* maker,
// Invoke the JavaScript factory method. If an exception is thrown while
// running the factory method, use the exception as the result.
- bool caught_exception;
- Handle<Object> result = Execution::TryCall(fun,
- isolate()->js_builtins_object(),
- ARRAY_SIZE(argv),
- argv,
- &caught_exception);
+ Handle<Object> result;
+ Handle<Object> exception;
+ if (!Execution::TryCall(fun,
+ isolate()->js_builtins_object(),
+ ARRAY_SIZE(argv),
+ argv,
+ &exception).ToHandle(&result)) {
+ return exception;
+ }
return result;
}
@@ -1186,41 +1158,104 @@ Handle<Object> Factory::NewError(Handle<String> message) {
Handle<Object> Factory::NewError(const char* constructor,
Handle<String> message) {
Handle<String> constr = InternalizeUtf8String(constructor);
- Handle<JSFunction> fun = Handle<JSFunction>(
- JSFunction::cast(isolate()->js_builtins_object()->
- GetPropertyNoExceptionThrown(*constr)));
+ Handle<JSFunction> fun = Handle<JSFunction>::cast(Object::GetProperty(
+ isolate()->js_builtins_object(), constr).ToHandleChecked());
Handle<Object> argv[] = { message };
// Invoke the JavaScript factory method. If an exception is thrown while
// running the factory method, use the exception as the result.
- bool caught_exception;
- Handle<Object> result = Execution::TryCall(fun,
- isolate()->js_builtins_object(),
- ARRAY_SIZE(argv),
- argv,
- &caught_exception);
+ Handle<Object> result;
+ Handle<Object> exception;
+ if (!Execution::TryCall(fun,
+ isolate()->js_builtins_object(),
+ ARRAY_SIZE(argv),
+ argv,
+ &exception).ToHandle(&result)) {
+ return exception;
+ }
+ return result;
+}
+
+
+void Factory::InitializeFunction(Handle<JSFunction> function,
+ Handle<SharedFunctionInfo> info,
+ Handle<Context> context) {
+ function->initialize_properties();
+ function->initialize_elements();
+ function->set_shared(*info);
+ function->set_code(info->code());
+ function->set_context(*context);
+ function->set_prototype_or_initial_map(*the_hole_value());
+ function->set_literals_or_bindings(*empty_fixed_array());
+ function->set_next_function_link(*undefined_value());
+}
+
+
+Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
+ Handle<SharedFunctionInfo> info,
+ Handle<Context> context,
+ PretenureFlag pretenure) {
+ AllocationSpace space = pretenure == TENURED ? OLD_POINTER_SPACE : NEW_SPACE;
+ Handle<JSFunction> result = New<JSFunction>(map, space);
+ InitializeFunction(result, info, context);
return result;
}
Handle<JSFunction> Factory::NewFunction(Handle<String> name,
+ Handle<Code> code,
+ MaybeHandle<Object> maybe_prototype) {
+ Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name);
+ ASSERT(info->strict_mode() == SLOPPY);
+ info->set_code(*code);
+ Handle<Context> context(isolate()->context()->native_context());
+ Handle<Map> map = maybe_prototype.is_null()
+ ? isolate()->sloppy_function_without_prototype_map()
+ : isolate()->sloppy_function_map();
+ Handle<JSFunction> result = NewFunction(map, info, context);
+ Handle<Object> prototype;
+ if (maybe_prototype.ToHandle(&prototype)) {
+ result->set_prototype_or_initial_map(*prototype);
+ }
+ return result;
+}
+
+
+Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
+ Handle<Object> prototype) {
+ Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name);
+ ASSERT(info->strict_mode() == SLOPPY);
+ Handle<Context> context(isolate()->context()->native_context());
+ Handle<Map> map = isolate()->sloppy_function_map();
+ Handle<JSFunction> result = NewFunction(map, info, context);
+ result->set_prototype_or_initial_map(*prototype);
+ return result;
+}
+
+
+Handle<JSFunction> Factory::NewFunction(MaybeHandle<Object> maybe_prototype,
+ Handle<String> name,
InstanceType type,
int instance_size,
Handle<Code> code,
bool force_initial_map) {
// Allocate the function
- Handle<JSFunction> function = NewFunction(name, the_hole_value());
-
- // Set up the code pointer in both the shared function info and in
- // the function itself.
- function->shared()->set_code(*code);
- function->set_code(*code);
+ Handle<JSFunction> function = NewFunction(name, code, maybe_prototype);
if (force_initial_map ||
type != JS_OBJECT_TYPE ||
instance_size != JSObject::kHeaderSize) {
+ Handle<Object> prototype = maybe_prototype.ToHandleChecked();
Handle<Map> initial_map = NewMap(type, instance_size);
- Handle<JSObject> prototype = NewFunctionPrototype(function);
+ if (prototype->IsJSObject()) {
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ Handle<JSObject>::cast(prototype),
+ constructor_string(),
+ function,
+ DONT_ENUM).Assert();
+ } else if (!function->shared()->is_generator()) {
+ prototype = NewFunctionPrototype(function);
+ }
initial_map->set_prototype(*prototype);
function->set_initial_map(*initial_map);
initial_map->set_constructor(*function);
@@ -1233,6 +1268,16 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name,
}
+Handle<JSFunction> Factory::NewFunction(Handle<String> name,
+ InstanceType type,
+ int instance_size,
+ Handle<Code> code,
+ bool force_initial_map) {
+ return NewFunction(
+ the_hole_value(), name, type, instance_size, code, force_initial_map);
+}
+
+
Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
InstanceType type,
int instance_size,
@@ -1240,12 +1285,7 @@ Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
Handle<Code> code,
bool force_initial_map) {
// Allocate the function.
- Handle<JSFunction> function = NewFunction(name, prototype);
-
- // Set up the code pointer in both the shared function info and in
- // the function itself.
- function->shared()->set_code(*code);
- function->set_code(*code);
+ Handle<JSFunction> function = NewFunction(name, code, prototype);
if (force_initial_map ||
type != JS_OBJECT_TYPE ||
@@ -1262,29 +1302,119 @@ Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
}
-Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name,
- Handle<Code> code) {
- Handle<JSFunction> function = NewFunctionWithoutPrototype(name, SLOPPY);
- function->shared()->set_code(*code);
- function->set_code(*code);
- ASSERT(!function->has_initial_map());
- ASSERT(!function->has_prototype());
- return function;
+Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
+ // Make sure to use globals from the function's context, since the function
+ // can be from a different context.
+ Handle<Context> native_context(function->context()->native_context());
+ Handle<Map> new_map;
+ if (function->shared()->is_generator()) {
+ // Generator prototypes can share maps since they don't have "constructor"
+ // properties.
+ new_map = handle(native_context->generator_object_prototype_map());
+ } else {
+ // Each function prototype gets a fresh map to avoid unwanted sharing of
+ // maps between prototypes of different constructors.
+ Handle<JSFunction> object_function(native_context->object_function());
+ ASSERT(object_function->has_initial_map());
+ new_map = Map::Copy(handle(object_function->initial_map()));
+ }
+
+ Handle<JSObject> prototype = NewJSObjectFromMap(new_map);
+
+ if (!function->shared()->is_generator()) {
+ JSObject::SetLocalPropertyIgnoreAttributes(prototype,
+ constructor_string(),
+ function,
+ DONT_ENUM).Assert();
+ }
+
+ return prototype;
+}
+
+
+Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
+ Handle<SharedFunctionInfo> info,
+ Handle<Context> context,
+ PretenureFlag pretenure) {
+ int map_index = Context::FunctionMapIndex(info->strict_mode(),
+ info->is_generator());
+ Handle<Map> map(Map::cast(context->native_context()->get(map_index)));
+ Handle<JSFunction> result = NewFunction(map, info, context, pretenure);
+
+ if (info->ic_age() != isolate()->heap()->global_ic_age()) {
+ info->ResetForNewContext(isolate()->heap()->global_ic_age());
+ }
+
+ int index = info->SearchOptimizedCodeMap(context->native_context(),
+ BailoutId::None());
+ if (!info->bound() && index < 0) {
+ int number_of_literals = info->num_literals();
+ Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure);
+ if (number_of_literals > 0) {
+ // Store the native context in the literals array prefix. This
+ // context will be used when creating object, regexp and array
+ // literals in this function.
+ literals->set(JSFunction::kLiteralNativeContextIndex,
+ context->native_context());
+ }
+ result->set_literals(*literals);
+ }
+
+ if (index > 0) {
+ // Caching of optimized code enabled and optimized code found.
+ FixedArray* literals = info->GetLiteralsFromOptimizedCodeMap(index);
+ if (literals != NULL) result->set_literals(literals);
+ Code* code = info->GetCodeFromOptimizedCodeMap(index);
+ ASSERT(!code->marked_for_deoptimization());
+ result->ReplaceCode(code);
+ return result;
+ }
+
+ if (isolate()->use_crankshaft() &&
+ FLAG_always_opt &&
+ result->is_compiled() &&
+ !info->is_toplevel() &&
+ info->allows_lazy_compilation() &&
+ !info->optimization_disabled() &&
+ !isolate()->DebuggerHasBreakPoints()) {
+ result->MarkForOptimization();
+ }
+ return result;
+}
+
+
+Handle<JSObject> Factory::NewIteratorResultObject(Handle<Object> value,
+ bool done) {
+ Handle<Map> map(isolate()->native_context()->iterator_result_map());
+ Handle<JSObject> result = NewJSObjectFromMap(map, NOT_TENURED, false);
+ result->InObjectPropertyAtPut(
+ JSGeneratorObject::kResultValuePropertyIndex, *value);
+ result->InObjectPropertyAtPut(
+ JSGeneratorObject::kResultDonePropertyIndex, *ToBoolean(done));
+ return result;
}
Handle<ScopeInfo> Factory::NewScopeInfo(int length) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateScopeInfo(length),
- ScopeInfo);
+ Handle<FixedArray> array = NewFixedArray(length, TENURED);
+ array->set_map_no_write_barrier(*scope_info_map());
+ Handle<ScopeInfo> scope_info = Handle<ScopeInfo>::cast(array);
+ return scope_info;
}
Handle<JSObject> Factory::NewExternal(void* value) {
+ Handle<Foreign> foreign = NewForeign(static_cast<Address>(value));
+ Handle<JSObject> external = NewJSObjectFromMap(external_map());
+ external->SetInternalField(0, *foreign);
+ return external;
+}
+
+
+Handle<Code> Factory::NewCodeRaw(int object_size, bool immovable) {
CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->AllocateExternal(value),
- JSObject);
+ isolate()->heap()->AllocateCode(object_size, immovable),
+ Code);
}
@@ -1294,11 +1424,60 @@ Handle<Code> Factory::NewCode(const CodeDesc& desc,
bool immovable,
bool crankshafted,
int prologue_offset) {
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->CreateCode(
- desc, flags, self_ref, immovable, crankshafted,
- prologue_offset),
- Code);
+ Handle<ByteArray> reloc_info = NewByteArray(desc.reloc_size, TENURED);
+ Handle<ConstantPoolArray> constant_pool =
+ desc.origin->NewConstantPool(isolate());
+
+ // Compute size.
+ int body_size = RoundUp(desc.instr_size, kObjectAlignment);
+ int obj_size = Code::SizeFor(body_size);
+
+ Handle<Code> code = NewCodeRaw(obj_size, immovable);
+ ASSERT(!isolate()->code_range()->exists() ||
+ isolate()->code_range()->contains(code->address()));
+
+ // The code object has not been fully initialized yet. We rely on the
+ // fact that no allocation will happen from this point on.
+ DisallowHeapAllocation no_gc;
+ code->set_gc_metadata(Smi::FromInt(0));
+ code->set_ic_age(isolate()->heap()->global_ic_age());
+ code->set_instruction_size(desc.instr_size);
+ code->set_relocation_info(*reloc_info);
+ code->set_flags(flags);
+ code->set_raw_kind_specific_flags1(0);
+ code->set_raw_kind_specific_flags2(0);
+ code->set_is_crankshafted(crankshafted);
+ code->set_deoptimization_data(*empty_fixed_array(), SKIP_WRITE_BARRIER);
+ code->set_raw_type_feedback_info(*undefined_value());
+ code->set_next_code_link(*undefined_value());
+ code->set_handler_table(*empty_fixed_array(), SKIP_WRITE_BARRIER);
+ code->set_prologue_offset(prologue_offset);
+ if (code->kind() == Code::OPTIMIZED_FUNCTION) {
+ code->set_marked_for_deoptimization(false);
+ }
+
+ desc.origin->PopulateConstantPool(*constant_pool);
+ code->set_constant_pool(*constant_pool);
+
+ if (code->kind() == Code::FUNCTION) {
+ code->set_has_debug_break_slots(isolate()->debugger()->IsDebuggerActive());
+ }
+
+ // Allow self references to created code object by patching the handle to
+ // point to the newly allocated Code object.
+ if (!self_ref.is_null()) *(self_ref.location()) = *code;
+
+ // Migrate generated code.
+ // The generated code can contain Object** values (typically from handles)
+ // that are dereferenced during the copy to point directly to the actual heap
+ // objects. These pointers can include references to the code object itself,
+ // through the self_reference parameter.
+ code->CopyFrom(desc);
+
+#ifdef VERIFY_HEAP
+ if (FLAG_verify_heap) code->ObjectVerify();
+#endif
+ return code;
}
@@ -1338,28 +1517,14 @@ Handle<JSObject> Factory::NewJSObjectWithMemento(
Handle<JSModule> Factory::NewJSModule(Handle<Context> context,
Handle<ScopeInfo> scope_info) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateJSModule(*context, *scope_info), JSModule);
-}
-
-
-// TODO(mstarzinger): Temporary wrapper until handlified.
-static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict,
- Handle<Name> name,
- Handle<Object> value,
- PropertyDetails details) {
- CALL_HEAP_FUNCTION(dict->GetIsolate(),
- dict->Add(*name, *value, details),
- NameDictionary);
-}
-
-
-static Handle<GlobalObject> NewGlobalObjectFromMap(Isolate* isolate,
- Handle<Map> map) {
- CALL_HEAP_FUNCTION(isolate,
- isolate->heap()->Allocate(*map, OLD_POINTER_SPACE),
- GlobalObject);
+ // Allocate a fresh map. Modules do not have a prototype.
+ Handle<Map> map = NewMap(JS_MODULE_TYPE, JSModule::kSize);
+ // Allocate the object based on the map.
+ Handle<JSModule> module =
+ Handle<JSModule>::cast(NewJSObjectFromMap(map, TENURED));
+ module->set_context(*context);
+ module->set_scope_info(*scope_info);
+ return module;
}
@@ -1385,7 +1550,8 @@ Handle<GlobalObject> Factory::NewGlobalObject(Handle<JSFunction> constructor) {
// Allocate a dictionary object for backing storage.
int at_least_space_for = map->NumberOfOwnDescriptors() * 2 + initial_size;
- Handle<NameDictionary> dictionary = NewNameDictionary(at_least_space_for);
+ Handle<NameDictionary> dictionary =
+ NameDictionary::New(isolate(), at_least_space_for);
// The global object might be created from an object template with accessors.
// Fill these accessors into the dictionary.
@@ -1397,11 +1563,12 @@ Handle<GlobalObject> Factory::NewGlobalObject(Handle<JSFunction> constructor) {
Handle<Name> name(descs->GetKey(i));
Handle<Object> value(descs->GetCallbacksObject(i), isolate());
Handle<PropertyCell> cell = NewPropertyCell(value);
- NameDictionaryAdd(dictionary, name, cell, d);
+ // |dictionary| already contains enough space for all properties.
+ USE(NameDictionary::Add(dictionary, name, cell, d));
}
// Allocate the global object and initialize it with the backing store.
- Handle<GlobalObject> global = NewGlobalObjectFromMap(isolate(), map);
+ Handle<GlobalObject> global = New<GlobalObject>(map, OLD_POINTER_SPACE);
isolate()->heap()->InitializeJSObjectFromMap(*global, *dictionary, *map);
// Create a new map for the global object.
@@ -1435,21 +1602,24 @@ Handle<JSObject> Factory::NewJSObjectFromMap(
Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind,
+ PretenureFlag pretenure) {
+ Context* native_context = isolate()->context()->native_context();
+ JSFunction* array_function = native_context->array_function();
+ Map* map = array_function->initial_map();
+ Map* transition_map = isolate()->get_initial_js_array_map(elements_kind);
+ if (transition_map != NULL) map = transition_map;
+ return Handle<JSArray>::cast(NewJSObjectFromMap(handle(map), pretenure));
+}
+
+
+Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind,
int length,
int capacity,
ArrayStorageAllocationMode mode,
PretenureFlag pretenure) {
- if (capacity != 0) {
- elements_kind = GetHoleyElementsKind(elements_kind);
- }
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->AllocateJSArrayAndStorage(
- elements_kind,
- length,
- capacity,
- mode,
- pretenure),
- JSArray);
+ Handle<JSArray> array = NewJSArray(elements_kind, pretenure);
+ NewJSArrayStorage(array, length, capacity, mode);
+ return array;
}
@@ -1458,25 +1628,48 @@ Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements,
int length,
PretenureFlag pretenure) {
ASSERT(length <= elements->length());
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateJSArrayWithElements(*elements,
- elements_kind,
- length,
- pretenure),
- JSArray);
+ Handle<JSArray> array = NewJSArray(elements_kind, pretenure);
+
+ array->set_elements(*elements);
+ array->set_length(Smi::FromInt(length));
+ JSObject::ValidateElements(array);
+ return array;
}
void Factory::NewJSArrayStorage(Handle<JSArray> array,
- int length,
- int capacity,
- ArrayStorageAllocationMode mode) {
- CALL_HEAP_FUNCTION_VOID(isolate(),
- isolate()->heap()->AllocateJSArrayStorage(*array,
- length,
- capacity,
- mode));
+ int length,
+ int capacity,
+ ArrayStorageAllocationMode mode) {
+ ASSERT(capacity >= length);
+
+ if (capacity == 0) {
+ array->set_length(Smi::FromInt(0));
+ array->set_elements(*empty_fixed_array());
+ return;
+ }
+
+ Handle<FixedArrayBase> elms;
+ ElementsKind elements_kind = array->GetElementsKind();
+ if (IsFastDoubleElementsKind(elements_kind)) {
+ if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
+ elms = NewFixedDoubleArray(capacity);
+ } else {
+ ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
+ elms = NewFixedDoubleArrayWithHoles(capacity);
+ }
+ } else {
+ ASSERT(IsFastSmiOrObjectElementsKind(elements_kind));
+ if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
+ elms = NewUninitializedFixedArray(capacity);
+ } else {
+ ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
+ elms = NewFixedArrayWithHoles(capacity);
+ }
+ }
+
+ array->set_elements(*elms);
+ array->set_length(Smi::FromInt(length));
}
@@ -1543,26 +1736,152 @@ Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type) {
Handle<JSProxy> Factory::NewJSProxy(Handle<Object> handler,
Handle<Object> prototype) {
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateJSProxy(*handler, *prototype),
- JSProxy);
+ // Allocate map.
+ // TODO(rossberg): Once we optimize proxies, think about a scheme to share
+ // maps. Will probably depend on the identity of the handler object, too.
+ Handle<Map> map = NewMap(JS_PROXY_TYPE, JSProxy::kSize);
+ map->set_prototype(*prototype);
+
+ // Allocate the proxy object.
+ Handle<JSProxy> result = New<JSProxy>(map, NEW_SPACE);
+ result->InitializeBody(map->instance_size(), Smi::FromInt(0));
+ result->set_handler(*handler);
+ result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER);
+ return result;
+}
+
+
+Handle<JSProxy> Factory::NewJSFunctionProxy(Handle<Object> handler,
+ Handle<Object> call_trap,
+ Handle<Object> construct_trap,
+ Handle<Object> prototype) {
+ // Allocate map.
+ // TODO(rossberg): Once we optimize proxies, think about a scheme to share
+ // maps. Will probably depend on the identity of the handler object, too.
+ Handle<Map> map = NewMap(JS_FUNCTION_PROXY_TYPE, JSFunctionProxy::kSize);
+ map->set_prototype(*prototype);
+
+ // Allocate the proxy object.
+ Handle<JSFunctionProxy> result = New<JSFunctionProxy>(map, NEW_SPACE);
+ result->InitializeBody(map->instance_size(), Smi::FromInt(0));
+ result->set_handler(*handler);
+ result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER);
+ result->set_call_trap(*call_trap);
+ result->set_construct_trap(*construct_trap);
+ return result;
+}
+
+
+void Factory::ReinitializeJSReceiver(Handle<JSReceiver> object,
+ InstanceType type,
+ int size) {
+ ASSERT(type >= FIRST_JS_OBJECT_TYPE);
+
+ // Allocate fresh map.
+ // TODO(rossberg): Once we optimize proxies, cache these maps.
+ Handle<Map> map = NewMap(type, size);
+
+ // Check that the receiver has at least the size of the fresh object.
+ int size_difference = object->map()->instance_size() - map->instance_size();
+ ASSERT(size_difference >= 0);
+
+ map->set_prototype(object->map()->prototype());
+
+ // Allocate the backing storage for the properties.
+ int prop_size = map->InitialPropertiesLength();
+ Handle<FixedArray> properties = NewFixedArray(prop_size, TENURED);
+
+ Heap* heap = isolate()->heap();
+ MaybeHandle<SharedFunctionInfo> shared;
+ if (type == JS_FUNCTION_TYPE) {
+ OneByteStringKey key(STATIC_ASCII_VECTOR("<freezing call trap>"),
+ heap->HashSeed());
+ Handle<String> name = InternalizeStringWithKey(&key);
+ shared = NewSharedFunctionInfo(name);
+ }
+
+ // In order to keep heap in consistent state there must be no allocations
+ // before object re-initialization is finished and filler object is installed.
+ DisallowHeapAllocation no_allocation;
+
+ // Reset the map for the object.
+ object->set_map(*map);
+ Handle<JSObject> jsobj = Handle<JSObject>::cast(object);
+
+ // Reinitialize the object from the constructor map.
+ heap->InitializeJSObjectFromMap(*jsobj, *properties, *map);
+
+ // Functions require some minimal initialization.
+ if (type == JS_FUNCTION_TYPE) {
+ map->set_function_with_prototype(true);
+ Handle<JSFunction> js_function = Handle<JSFunction>::cast(object);
+ Handle<Context> context(isolate()->context()->native_context());
+ InitializeFunction(js_function, shared.ToHandleChecked(), context);
+ }
+
+ // Put in filler if the new object is smaller than the old.
+ if (size_difference > 0) {
+ heap->CreateFillerObjectAt(
+ object->address() + map->instance_size(), size_difference);
+ }
+}
+
+
+void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object,
+ Handle<JSFunction> constructor) {
+ ASSERT(constructor->has_initial_map());
+ Handle<Map> map(constructor->initial_map(), isolate());
+
+ // The proxy's hash should be retained across reinitialization.
+ Handle<Object> hash(object->hash(), isolate());
+
+ // Check that the already allocated object has the same size and type as
+ // objects allocated using the constructor.
+ ASSERT(map->instance_size() == object->map()->instance_size());
+ ASSERT(map->instance_type() == object->map()->instance_type());
+
+ // Allocate the backing storage for the properties.
+ int prop_size = map->InitialPropertiesLength();
+ Handle<FixedArray> properties = NewFixedArray(prop_size, TENURED);
+
+ // In order to keep heap in consistent state there must be no allocations
+ // before object re-initialization is finished.
+ DisallowHeapAllocation no_allocation;
+
+ // Reset the map for the object.
+ object->set_map(constructor->initial_map());
+
+ Heap* heap = isolate()->heap();
+ // Reinitialize the object from the constructor map.
+ heap->InitializeJSObjectFromMap(*object, *properties, *map);
+
+ // Restore the saved hash.
+ object->set_hash(*hash);
}
void Factory::BecomeJSObject(Handle<JSReceiver> object) {
- CALL_HEAP_FUNCTION_VOID(
- isolate(),
- isolate()->heap()->ReinitializeJSReceiver(
- *object, JS_OBJECT_TYPE, JSObject::kHeaderSize));
+ ReinitializeJSReceiver(object, JS_OBJECT_TYPE, JSObject::kHeaderSize);
}
void Factory::BecomeJSFunction(Handle<JSReceiver> object) {
- CALL_HEAP_FUNCTION_VOID(
+ ReinitializeJSReceiver(object, JS_FUNCTION_TYPE, JSFunction::kSize);
+}
+
+
+Handle<FixedArray> Factory::NewTypeFeedbackVector(int slot_count) {
+ // Ensure we can skip the write barrier
+ ASSERT_EQ(isolate()->heap()->uninitialized_symbol(),
+ *TypeFeedbackInfo::UninitializedSentinel(isolate()));
+
+ CALL_HEAP_FUNCTION(
isolate(),
- isolate()->heap()->ReinitializeJSReceiver(
- *object, JS_FUNCTION_TYPE, JSFunction::kSize));
+ isolate()->heap()->AllocateFixedArrayWithFiller(
+ slot_count,
+ TENURED,
+ *TypeFeedbackInfo::UninitializedSentinel(isolate())),
+ FixedArray);
}
@@ -1571,10 +1890,12 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
int number_of_literals,
bool is_generator,
Handle<Code> code,
- Handle<ScopeInfo> scope_info) {
+ Handle<ScopeInfo> scope_info,
+ Handle<FixedArray> feedback_vector) {
Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name);
shared->set_code(*code);
shared->set_scope_info(*scope_info);
+ shared->set_feedback_vector(*feedback_vector);
int literals_array_size = number_of_literals;
// If the function contains object, regexp or array literals,
// allocate extra space for a literals array prefix containing the
@@ -1598,113 +1919,137 @@ Handle<JSMessageObject> Factory::NewJSMessageObject(
int end_position,
Handle<Object> script,
Handle<Object> stack_frames) {
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->AllocateJSMessageObject(*type,
- *arguments,
- start_position,
- end_position,
- *script,
- *stack_frames),
- JSMessageObject);
+ Handle<Map> map = message_object_map();
+ Handle<JSMessageObject> message = New<JSMessageObject>(map, NEW_SPACE);
+ message->set_properties(*empty_fixed_array(), SKIP_WRITE_BARRIER);
+ message->initialize_elements();
+ message->set_elements(*empty_fixed_array(), SKIP_WRITE_BARRIER);
+ message->set_type(*type);
+ message->set_arguments(*arguments);
+ message->set_start_position(start_position);
+ message->set_end_position(end_position);
+ message->set_script(*script);
+ message->set_stack_frames(*stack_frames);
+ return message;
}
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(Handle<String> name) {
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->AllocateSharedFunctionInfo(*name),
- SharedFunctionInfo);
-}
-
-
-Handle<String> Factory::NumberToString(Handle<Object> number) {
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->NumberToString(*number), String);
-}
-
-
-Handle<String> Factory::Uint32ToString(uint32_t value) {
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->Uint32ToString(value), String);
-}
-
-
-Handle<SeededNumberDictionary> Factory::DictionaryAtNumberPut(
- Handle<SeededNumberDictionary> dictionary,
- uint32_t key,
- Handle<Object> value) {
- CALL_HEAP_FUNCTION(isolate(),
- dictionary->AtNumberPut(key, *value),
- SeededNumberDictionary);
-}
-
-
-Handle<UnseededNumberDictionary> Factory::DictionaryAtNumberPut(
- Handle<UnseededNumberDictionary> dictionary,
- uint32_t key,
- Handle<Object> value) {
- CALL_HEAP_FUNCTION(isolate(),
- dictionary->AtNumberPut(key, *value),
- UnseededNumberDictionary);
-}
-
-
-Handle<JSFunction> Factory::NewFunctionHelper(Handle<String> name,
- Handle<Object> prototype) {
- Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
- CALL_HEAP_FUNCTION(
- isolate(),
- isolate()->heap()->AllocateFunction(*isolate()->sloppy_function_map(),
- *function_share,
- *prototype),
- JSFunction);
-}
-
-
-Handle<JSFunction> Factory::NewFunction(Handle<String> name,
- Handle<Object> prototype) {
- Handle<JSFunction> fun = NewFunctionHelper(name, prototype);
- fun->set_context(isolate()->context()->native_context());
- return fun;
-}
-
-
-Handle<JSFunction> Factory::NewFunctionWithoutPrototypeHelper(
- Handle<String> name,
- StrictMode strict_mode) {
- Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
- Handle<Map> map = strict_mode == SLOPPY
- ? isolate()->sloppy_function_without_prototype_map()
- : isolate()->strict_function_without_prototype_map();
- CALL_HEAP_FUNCTION(isolate(),
- isolate()->heap()->AllocateFunction(
- *map,
- *function_share,
- *the_hole_value()),
- JSFunction);
+ Handle<Map> map = shared_function_info_map();
+ Handle<SharedFunctionInfo> share = New<SharedFunctionInfo>(map,
+ OLD_POINTER_SPACE);
+
+ // Set pointer fields.
+ share->set_name(*name);
+ Code* illegal = isolate()->builtins()->builtin(Builtins::kIllegal);
+ share->set_code(illegal);
+ share->set_optimized_code_map(Smi::FromInt(0));
+ share->set_scope_info(ScopeInfo::Empty(isolate()));
+ Code* construct_stub =
+ isolate()->builtins()->builtin(Builtins::kJSConstructStubGeneric);
+ share->set_construct_stub(construct_stub);
+ share->set_instance_class_name(*Object_string());
+ share->set_function_data(*undefined_value(), SKIP_WRITE_BARRIER);
+ share->set_script(*undefined_value(), SKIP_WRITE_BARRIER);
+ share->set_debug_info(*undefined_value(), SKIP_WRITE_BARRIER);
+ share->set_inferred_name(*empty_string(), SKIP_WRITE_BARRIER);
+ share->set_feedback_vector(*empty_fixed_array(), SKIP_WRITE_BARRIER);
+ share->set_initial_map(*undefined_value(), SKIP_WRITE_BARRIER);
+ share->set_profiler_ticks(0);
+ share->set_ast_node_count(0);
+ share->set_counters(0);
+
+ // Set integer fields (smi or int, depending on the architecture).
+ share->set_length(0);
+ share->set_formal_parameter_count(0);
+ share->set_expected_nof_properties(0);
+ share->set_num_literals(0);
+ share->set_start_position_and_type(0);
+ share->set_end_position(0);
+ share->set_function_token_position(0);
+ // All compiler hints default to false or 0.
+ share->set_compiler_hints(0);
+ share->set_opt_count_and_bailout_reason(0);
+
+ return share;
+}
+
+
+static inline int NumberCacheHash(Handle<FixedArray> cache,
+ Handle<Object> number) {
+ int mask = (cache->length() >> 1) - 1;
+ if (number->IsSmi()) {
+ return Handle<Smi>::cast(number)->value() & mask;
+ } else {
+ DoubleRepresentation rep(number->Number());
+ return
+ (static_cast<int>(rep.bits) ^ static_cast<int>(rep.bits >> 32)) & mask;
+ }
}
-Handle<JSFunction> Factory::NewFunctionWithoutPrototype(
- Handle<String> name,
- StrictMode strict_mode) {
- Handle<JSFunction> fun = NewFunctionWithoutPrototypeHelper(name, strict_mode);
- fun->set_context(isolate()->context()->native_context());
- return fun;
+Handle<Object> Factory::GetNumberStringCache(Handle<Object> number) {
+ DisallowHeapAllocation no_gc;
+ int hash = NumberCacheHash(number_string_cache(), number);
+ Object* key = number_string_cache()->get(hash * 2);
+ if (key == *number || (key->IsHeapNumber() && number->IsHeapNumber() &&
+ key->Number() == number->Number())) {
+ return Handle<String>(
+ String::cast(number_string_cache()->get(hash * 2 + 1)), isolate());
+ }
+ return undefined_value();
+}
+
+
+void Factory::SetNumberStringCache(Handle<Object> number,
+ Handle<String> string) {
+ int hash = NumberCacheHash(number_string_cache(), number);
+ if (number_string_cache()->get(hash * 2) != *undefined_value()) {
+ int full_size = isolate()->heap()->FullSizeNumberStringCacheLength();
+ if (number_string_cache()->length() != full_size) {
+ // The first time we have a hash collision, we move to the full sized
+ // number string cache. The idea is to have a small number string
+ // cache in the snapshot to keep boot-time memory usage down.
+ // If we expand the number string cache already while creating
+ // the snapshot then that didn't work out.
+ ASSERT(!Serializer::enabled(isolate()) || FLAG_extra_code != NULL);
+ Handle<FixedArray> new_cache = NewFixedArray(full_size, TENURED);
+ isolate()->heap()->set_number_string_cache(*new_cache);
+ return;
+ }
+ }
+ number_string_cache()->set(hash * 2, *number);
+ number_string_cache()->set(hash * 2 + 1, *string);
}
-Handle<Object> Factory::ToObject(Handle<Object> object) {
- CALL_HEAP_FUNCTION(isolate(), object->ToObject(isolate()), Object);
-}
+Handle<String> Factory::NumberToString(Handle<Object> number,
+ bool check_number_string_cache) {
+ isolate()->counters()->number_to_string_runtime()->Increment();
+ if (check_number_string_cache) {
+ Handle<Object> cached = GetNumberStringCache(number);
+ if (!cached->IsUndefined()) return Handle<String>::cast(cached);
+ }
+ char arr[100];
+ Vector<char> buffer(arr, ARRAY_SIZE(arr));
+ const char* str;
+ if (number->IsSmi()) {
+ int num = Handle<Smi>::cast(number)->value();
+ str = IntToCString(num, buffer);
+ } else {
+ double num = Handle<HeapNumber>::cast(number)->value();
+ str = DoubleToCString(num, buffer);
+ }
-Handle<Object> Factory::ToObject(Handle<Object> object,
- Handle<Context> native_context) {
- CALL_HEAP_FUNCTION(isolate(), object->ToObject(*native_context), Object);
+ // We tenure the allocated string since it is referenced from the
+ // number-string cache which lives in the old space.
+ Handle<String> js_string = NewStringFromAsciiChecked(str, TENURED);
+ SetNumberStringCache(number, js_string);
+ return js_string;
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
// Get the original code of the function.
Handle<Code> code(shared->code());
@@ -1734,7 +2079,6 @@ Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
return debug_info;
}
-#endif
Handle<JSObject> Factory::NewArgumentsObject(Handle<Object> callee,
@@ -1746,7 +2090,9 @@ Handle<JSObject> Factory::NewArgumentsObject(Handle<Object> callee,
Handle<JSFunction> Factory::CreateApiFunction(
- Handle<FunctionTemplateInfo> obj, ApiInstanceType instance_type) {
+ Handle<FunctionTemplateInfo> obj,
+ Handle<Object> prototype,
+ ApiInstanceType instance_type) {
Handle<Code> code = isolate()->builtins()->HandleApiCall();
Handle<Code> construct_stub = isolate()->builtins()->JSConstructStubApi();
@@ -1782,24 +2128,33 @@ Handle<JSFunction> Factory::CreateApiFunction(
break;
}
- Handle<JSFunction> result =
- NewFunction(Factory::empty_string(),
- type,
- instance_size,
- code,
- true);
+ MaybeHandle<Object> maybe_prototype = prototype;
+ if (obj->remove_prototype()) maybe_prototype = MaybeHandle<Object>();
- // Set length.
- result->shared()->set_length(obj->length());
+ Handle<JSFunction> result = NewFunction(
+ maybe_prototype, Factory::empty_string(), type,
+ instance_size, code, !obj->remove_prototype());
- // Set class name.
- Handle<Object> class_name = Handle<Object>(obj->class_name(), isolate());
+ result->shared()->set_length(obj->length());
+ Handle<Object> class_name(obj->class_name(), isolate());
if (class_name->IsString()) {
result->shared()->set_instance_class_name(*class_name);
result->shared()->set_name(*class_name);
}
+ result->shared()->set_function_data(*obj);
+ result->shared()->set_construct_stub(*construct_stub);
+ result->shared()->DontAdaptArguments();
+
+ if (obj->remove_prototype()) {
+ ASSERT(result->shared()->IsApiFunction());
+ ASSERT(!result->has_initial_map());
+ ASSERT(!result->has_prototype());
+ return result;
+ }
+ // Down from here is only valid for API functions that can be used as a
+ // constructor (don't set the "remove prototype" flag).
- Handle<Map> map = Handle<Map>(result->initial_map());
+ Handle<Map> map(result->initial_map());
// Mark as undetectable if needed.
if (obj->undetectable()) {
@@ -1829,10 +2184,6 @@ Handle<JSFunction> Factory::CreateApiFunction(
map->set_has_instance_call_handler();
}
- result->shared()->set_function_data(*obj);
- result->shared()->set_construct_stub(*construct_stub);
- result->shared()->DontAdaptArguments();
-
// Recursively copy parent instance templates' accessors,
// 'data' may be modified.
int max_number_of_additional_properties = 0;
@@ -1899,7 +2250,7 @@ Handle<JSFunction> Factory::CreateApiFunction(
// Install accumulated static accessors
for (int i = 0; i < valid_descriptors; i++) {
Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i)));
- JSObject::SetAccessor(result, accessor);
+ JSObject::SetAccessor(result, accessor).Assert();
}
ASSERT(result->shared()->IsApiFunction());
@@ -1907,32 +2258,13 @@ Handle<JSFunction> Factory::CreateApiFunction(
}
-Handle<MapCache> Factory::NewMapCache(int at_least_space_for) {
- CALL_HEAP_FUNCTION(isolate(),
- MapCache::Allocate(isolate()->heap(),
- at_least_space_for),
- MapCache);
-}
-
-
-MUST_USE_RESULT static MaybeObject* UpdateMapCacheWith(Context* context,
- FixedArray* keys,
- Map* map) {
- Object* result;
- { MaybeObject* maybe_result =
- MapCache::cast(context->map_cache())->Put(keys, map);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- context->set_map_cache(MapCache::cast(result));
- return result;
-}
-
-
Handle<MapCache> Factory::AddToMapCache(Handle<Context> context,
Handle<FixedArray> keys,
Handle<Map> map) {
- CALL_HEAP_FUNCTION(isolate(),
- UpdateMapCacheWith(*context, *keys, *map), MapCache);
+ Handle<MapCache> map_cache = handle(MapCache::cast(context->map_cache()));
+ Handle<MapCache> result = MapCache::Put(map_cache, keys, map);
+ context->set_map_cache(*result);
+ return result;
}
@@ -1940,7 +2272,7 @@ Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context,
Handle<FixedArray> keys) {
if (context->map_cache()->IsUndefined()) {
// Allocate the new map cache for the native context.
- Handle<MapCache> new_cache = NewMapCache(24);
+ Handle<MapCache> new_cache = MapCache::New(isolate(), 24);
context->set_map_cache(*new_cache);
}
// Check to see whether there is a matching element in the cache.
@@ -1949,11 +2281,10 @@ Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context,
Handle<Object> result = Handle<Object>(cache->Lookup(*keys), isolate());
if (result->IsMap()) return Handle<Map>::cast(result);
// Create a new map and add it to the cache.
- Handle<Map> map =
- CopyMap(Handle<Map>(context->object_function()->initial_map()),
- keys->length());
+ Handle<Map> map = Map::Create(
+ handle(context->object_function()), keys->length());
AddToMapCache(context, keys, map);
- return Handle<Map>(map);
+ return map;
}
@@ -1993,28 +2324,25 @@ void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp,
-void Factory::ConfigureInstance(Handle<FunctionTemplateInfo> desc,
- Handle<JSObject> instance,
- bool* pending_exception) {
+MaybeHandle<FunctionTemplateInfo> Factory::ConfigureInstance(
+ Handle<FunctionTemplateInfo> desc, Handle<JSObject> instance) {
// Configure the instance by adding the properties specified by the
// instance template.
Handle<Object> instance_template(desc->instance_template(), isolate());
if (!instance_template->IsUndefined()) {
- Execution::ConfigureInstance(isolate(),
- instance,
- instance_template,
- pending_exception);
- } else {
- *pending_exception = false;
+ RETURN_ON_EXCEPTION(
+ isolate(),
+ Execution::ConfigureInstance(isolate(), instance, instance_template),
+ FunctionTemplateInfo);
}
+ return desc;
}
Handle<Object> Factory::GlobalConstantFor(Handle<String> name) {
- Heap* h = isolate()->heap();
- if (name->Equals(h->undefined_string())) return undefined_value();
- if (name->Equals(h->nan_string())) return nan_value();
- if (name->Equals(h->infinity_string())) return infinity_value();
+ if (String::Equals(name, undefined_string())) return undefined_value();
+ if (String::Equals(name, nan_string())) return nan_value();
+ if (String::Equals(name, infinity_string())) return infinity_value();
return Handle<Object>::null();
}
diff --git a/deps/v8/src/factory.h b/deps/v8/src/factory.h
index 00f20ff8ba..91a036cca7 100644
--- a/deps/v8/src/factory.h
+++ b/deps/v8/src/factory.h
@@ -1,48 +1,23 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_FACTORY_H_
#define V8_FACTORY_H_
-#include "globals.h"
-#include "handles.h"
-#include "heap.h"
+#include "isolate.h"
namespace v8 {
namespace internal {
// Interface for handle based allocation.
-class Factory {
+class Factory V8_FINAL {
public:
- // Allocate a new boxed value.
- Handle<Box> NewBox(
- Handle<Object> value,
- PretenureFlag pretenure = NOT_TENURED);
+ Handle<Oddball> NewOddball(Handle<Map> map,
+ const char* to_string,
+ Handle<Object> to_number,
+ byte kind);
// Allocates a fixed array initialized with undefined values.
Handle<FixedArray> NewFixedArray(
@@ -58,7 +33,14 @@ class Factory {
Handle<FixedArray> NewUninitializedFixedArray(int size);
// Allocate a new uninitialized fixed double array.
- Handle<FixedDoubleArray> NewFixedDoubleArray(
+ // The function returns a pre-allocated empty fixed array for capacity = 0,
+ // so the return type must be the general fixed array class.
+ Handle<FixedArrayBase> NewFixedDoubleArray(
+ int size,
+ PretenureFlag pretenure = NOT_TENURED);
+
+ // Allocate a new fixed double array with hole values.
+ Handle<FixedArrayBase> NewFixedDoubleArrayWithHoles(
int size,
PretenureFlag pretenure = NOT_TENURED);
@@ -68,35 +50,20 @@ class Factory {
int number_of_heap_ptr_entries,
int number_of_int32_entries);
- Handle<SeededNumberDictionary> NewSeededNumberDictionary(
- int at_least_space_for);
-
- Handle<UnseededNumberDictionary> NewUnseededNumberDictionary(
- int at_least_space_for);
-
- Handle<NameDictionary> NewNameDictionary(int at_least_space_for);
+ Handle<OrderedHashSet> NewOrderedHashSet();
+ Handle<OrderedHashMap> NewOrderedHashMap();
- Handle<ObjectHashSet> NewObjectHashSet(int at_least_space_for);
+ // Create a new boxed value.
+ Handle<Box> NewBox(Handle<Object> value);
- Handle<ObjectHashTable> NewObjectHashTable(
- int at_least_space_for,
- MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY);
-
- Handle<WeakHashTable> NewWeakHashTable(int at_least_space_for);
-
- Handle<DescriptorArray> NewDescriptorArray(int number_of_descriptors,
- int slack = 0);
- Handle<DeoptimizationInputData> NewDeoptimizationInputData(
- int deopt_entry_count,
- PretenureFlag pretenure);
- Handle<DeoptimizationOutputData> NewDeoptimizationOutputData(
- int deopt_entry_count,
- PretenureFlag pretenure);
- // Allocates a pre-tenured empty AccessorPair.
+ // Create a pre-tenured empty AccessorPair.
Handle<AccessorPair> NewAccessorPair();
+ // Create an empty TypeFeedbackInfo.
Handle<TypeFeedbackInfo> NewTypeFeedbackInfo();
+ // Finds the internalized copy for string in the string table.
+ // If not found, a new string is added to the table and returned.
Handle<String> InternalizeUtf8String(Vector<const char> str);
Handle<String> InternalizeUtf8String(const char* str) {
return InternalizeUtf8String(CStrVector(str));
@@ -134,11 +101,28 @@ class Factory {
// two byte.
//
// ASCII strings are pretenured when used as keys in the SourceCodeCache.
- Handle<String> NewStringFromOneByte(
+ MUST_USE_RESULT MaybeHandle<String> NewStringFromOneByte(
Vector<const uint8_t> str,
PretenureFlag pretenure = NOT_TENURED);
+
+ template<size_t N>
+ inline Handle<String> NewStringFromStaticAscii(
+ const char (&str)[N],
+ PretenureFlag pretenure = NOT_TENURED) {
+ ASSERT(N == StrLength(str) + 1);
+ return NewStringFromOneByte(
+ STATIC_ASCII_VECTOR(str), pretenure).ToHandleChecked();
+ }
+
+ inline Handle<String> NewStringFromAsciiChecked(
+ const char* str,
+ PretenureFlag pretenure = NOT_TENURED) {
+ return NewStringFromOneByte(
+ OneByteVector(str), pretenure).ToHandleChecked();
+ }
+
// TODO(dcarney): remove this function.
- inline Handle<String> NewStringFromAscii(
+ MUST_USE_RESULT inline MaybeHandle<String> NewStringFromAscii(
Vector<const char> str,
PretenureFlag pretenure = NOT_TENURED) {
return NewStringFromOneByte(Vector<const uint8_t>::cast(str), pretenure);
@@ -146,29 +130,54 @@ class Factory {
// UTF8 strings are pretenured when used for regexp literal patterns and
// flags in the parser.
- Handle<String> NewStringFromUtf8(
+ MUST_USE_RESULT MaybeHandle<String> NewStringFromUtf8(
Vector<const char> str,
PretenureFlag pretenure = NOT_TENURED);
- Handle<String> NewStringFromTwoByte(
+ MUST_USE_RESULT MaybeHandle<String> NewStringFromTwoByte(
Vector<const uc16> str,
PretenureFlag pretenure = NOT_TENURED);
+ // Allocates an internalized string in old space based on the character
+ // stream.
+ MUST_USE_RESULT Handle<String> NewInternalizedStringFromUtf8(
+ Vector<const char> str,
+ int chars,
+ uint32_t hash_field);
+
+ MUST_USE_RESULT Handle<String> NewOneByteInternalizedString(
+ Vector<const uint8_t> str,
+ uint32_t hash_field);
+
+ MUST_USE_RESULT Handle<String> NewTwoByteInternalizedString(
+ Vector<const uc16> str,
+ uint32_t hash_field);
+
+ MUST_USE_RESULT Handle<String> NewInternalizedStringImpl(
+ Handle<String> string, int chars, uint32_t hash_field);
+
+ // Compute the matching internalized string map for a string if possible.
+ // Empty handle is returned if string is in new space or not flattened.
+ MUST_USE_RESULT MaybeHandle<Map> InternalizedStringMapForString(
+ Handle<String> string);
+
// Allocates and partially initializes an ASCII or TwoByte String. The
// characters of the string are uninitialized. Currently used in regexp code
// only, where they are pretenured.
- Handle<SeqOneByteString> NewRawOneByteString(
+ MUST_USE_RESULT MaybeHandle<SeqOneByteString> NewRawOneByteString(
int length,
PretenureFlag pretenure = NOT_TENURED);
- Handle<SeqTwoByteString> NewRawTwoByteString(
+ MUST_USE_RESULT MaybeHandle<SeqTwoByteString> NewRawTwoByteString(
int length,
PretenureFlag pretenure = NOT_TENURED);
- // Create a new cons string object which consists of a pair of strings.
- Handle<String> NewConsString(Handle<String> left,
- Handle<String> right);
+ // Creates a single character string where the character has given code.
+ // A cache is used for ASCII codes.
+ Handle<String> LookupSingleCharacterStringFromCode(uint32_t code);
- Handle<ConsString> NewRawConsString(String::Encoding encoding);
+ // Create a new cons string object which consists of a pair of strings.
+ MUST_USE_RESULT MaybeHandle<String> NewConsString(Handle<String> left,
+ Handle<String> right);
// Create a new sequential string containing the concatenation of the inputs.
Handle<String> NewFlatConcatString(Handle<String> first,
@@ -185,15 +194,14 @@ class Factory {
return NewProperSubString(str, begin, end);
}
- Handle<SlicedString> NewRawSlicedString(String::Encoding encoding);
-
// Creates a new external String object. There are two String encodings
// in the system: ASCII and two byte. Unlike other String types, it does
// not make sense to have a UTF-8 factory function for external strings,
- // because we cannot change the underlying buffer.
- Handle<String> NewExternalStringFromAscii(
+ // because we cannot change the underlying buffer. Note that these strings
+ // are backed by a string resource that resides outside the V8 heap.
+ MUST_USE_RESULT MaybeHandle<String> NewExternalStringFromAscii(
const ExternalAsciiString::Resource* resource);
- Handle<String> NewExternalStringFromTwoByte(
+ MUST_USE_RESULT MaybeHandle<String> NewExternalStringFromTwoByte(
const ExternalTwoByteString::Resource* resource);
// Create a symbol.
@@ -222,7 +230,7 @@ class Factory {
// Create a 'with' context.
Handle<Context> NewWithContext(Handle<JSFunction> function,
Handle<Context> previous,
- Handle<JSObject> extension);
+ Handle<JSReceiver> extension);
// Create a block context.
Handle<Context> NewBlockContext(Handle<JSFunction> function,
@@ -233,6 +241,8 @@ class Factory {
// the old generation).
Handle<Struct> NewStruct(InstanceType type);
+ Handle<CodeCache> NewCodeCache();
+
Handle<AliasedArgumentsEntry> NewAliasedArgumentsEntry(
int aliased_context_slot);
@@ -272,6 +282,7 @@ class Factory {
Handle<PropertyCell> NewPropertyCell(Handle<Object> value);
+ // Allocate a tenured AllocationSite. It's payload is null.
Handle<AllocationSite> NewAllocationSite();
Handle<Map> NewMap(
@@ -279,14 +290,19 @@ class Factory {
int instance_size,
ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND);
+ Handle<HeapObject> NewFillerObject(int size,
+ bool double_align,
+ AllocationSpace space);
+
Handle<JSObject> NewFunctionPrototype(Handle<JSFunction> function);
- Handle<Map> CopyWithPreallocatedFieldDescriptors(Handle<Map> map);
+ Handle<JSObject> CopyJSObject(Handle<JSObject> object);
+
+ Handle<JSObject> CopyJSObjectWithAllocationSite(Handle<JSObject> object,
+ Handle<AllocationSite> site);
- // Copy the map adding more inobject properties if possible without
- // overflowing the instance size.
- Handle<Map> CopyMap(Handle<Map> map, int extra_inobject_props);
- Handle<Map> CopyMap(Handle<Map> map);
+ Handle<FixedArray> CopyFixedArrayWithMap(Handle<FixedArray> array,
+ Handle<Map> map);
Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array);
@@ -294,10 +310,6 @@ class Factory {
// of it in old space.
Handle<FixedArray> CopyAndTenureFixedCOWArray(Handle<FixedArray> array);
- Handle<FixedArray> CopySizeFixedArray(Handle<FixedArray> array,
- int new_length,
- PretenureFlag pretenure = NOT_TENURED);
-
Handle<FixedDoubleArray> CopyFixedDoubleArray(
Handle<FixedDoubleArray> array);
@@ -305,6 +317,7 @@ class Factory {
Handle<ConstantPoolArray> array);
// Numbers (e.g. literals) are pretenured by the parser.
+ // The return value may be a smi or a heap number.
Handle<Object> NewNumber(double value,
PretenureFlag pretenure = NOT_TENURED);
@@ -312,15 +325,23 @@ class Factory {
PretenureFlag pretenure = NOT_TENURED);
Handle<Object> NewNumberFromUint(uint32_t value,
PretenureFlag pretenure = NOT_TENURED);
- inline Handle<Object> NewNumberFromSize(size_t value,
- PretenureFlag pretenure = NOT_TENURED);
+ Handle<Object> NewNumberFromSize(size_t value,
+ PretenureFlag pretenure = NOT_TENURED) {
+ if (Smi::IsValid(static_cast<intptr_t>(value))) {
+ return Handle<Object>(Smi::FromIntptr(static_cast<intptr_t>(value)),
+ isolate());
+ }
+ return NewNumber(static_cast<double>(value), pretenure);
+ }
Handle<HeapNumber> NewHeapNumber(double value,
PretenureFlag pretenure = NOT_TENURED);
// These objects are used by the api to create env-independent data
// structures in the heap.
- Handle<JSObject> NewNeanderObject();
+ inline Handle<JSObject> NewNeanderObject() {
+ return NewJSObjectFromMap(neander_map());
+ }
Handle<JSObject> NewArgumentsObject(Handle<Object> callee, int length);
@@ -343,14 +364,19 @@ class Factory {
bool allocate_properties = true,
Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null());
- Handle<JSObject> NewJSObjectFromMapForDeoptimizer(
- Handle<Map> map, PretenureFlag pretenure = NOT_TENURED);
-
// JS modules are pretenured.
Handle<JSModule> NewJSModule(Handle<Context> context,
Handle<ScopeInfo> scope_info);
// JS arrays are pretenured when allocated by the parser.
+
+ // Create a JSArray with no elements.
+ Handle<JSArray> NewJSArray(
+ ElementsKind elements_kind,
+ PretenureFlag pretenure = NOT_TENURED);
+
+ // Create a JSArray with a specified length and elements initialized
+ // according to the specified mode.
Handle<JSArray> NewJSArray(
ElementsKind elements_kind,
int length,
@@ -362,10 +388,14 @@ class Factory {
int capacity,
ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
PretenureFlag pretenure = NOT_TENURED) {
+ if (capacity != 0) {
+ elements_kind = GetHoleyElementsKind(elements_kind);
+ }
return NewJSArray(elements_kind, 0, capacity,
INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE, pretenure);
}
+ // Create a JSArray with the given elements.
Handle<JSArray> NewJSArrayWithElements(
Handle<FixedArrayBase> elements,
ElementsKind elements_kind,
@@ -394,35 +424,74 @@ class Factory {
Handle<JSDataView> NewJSDataView();
+ // Allocates a Harmony proxy.
Handle<JSProxy> NewJSProxy(Handle<Object> handler, Handle<Object> prototype);
+ // Allocates a Harmony function proxy.
+ Handle<JSProxy> NewJSFunctionProxy(Handle<Object> handler,
+ Handle<Object> call_trap,
+ Handle<Object> construct_trap,
+ Handle<Object> prototype);
+
+ // Reinitialize a JSReceiver into an (empty) JS object of respective type and
+ // size, but keeping the original prototype. The receiver must have at least
+ // the size of the new object. The object is reinitialized and behaves as an
+ // object that has been freshly allocated.
+ void ReinitializeJSReceiver(
+ Handle<JSReceiver> object, InstanceType type, int size);
+
+ // Reinitialize an JSGlobalProxy based on a constructor. The object
+ // must have the same size as objects allocated using the
+ // constructor. The object is reinitialized and behaves as an
+ // object that has been freshly allocated using the constructor.
+ void ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> global,
+ Handle<JSFunction> constructor);
+
// Change the type of the argument into a JS object/function and reinitialize.
void BecomeJSObject(Handle<JSReceiver> object);
void BecomeJSFunction(Handle<JSReceiver> object);
Handle<JSFunction> NewFunction(Handle<String> name,
- Handle<Object> prototype);
-
- Handle<JSFunction> NewFunctionWithoutPrototype(
- Handle<String> name,
- StrictMode strict_mode);
-
- Handle<JSFunction> NewFunction(Handle<Object> super, bool is_global);
+ Handle<Code> code,
+ MaybeHandle<Object> maybe_prototype =
+ MaybeHandle<Object>());
- Handle<JSFunction> BaseNewFunctionFromSharedFunctionInfo(
- Handle<SharedFunctionInfo> function_info,
- Handle<Map> function_map,
- PretenureFlag pretenure);
+ Handle<JSFunction> NewFunctionWithPrototype(Handle<String> name,
+ Handle<Object> prototype);
Handle<JSFunction> NewFunctionFromSharedFunctionInfo(
Handle<SharedFunctionInfo> function_info,
Handle<Context> context,
PretenureFlag pretenure = TENURED);
+ Handle<JSFunction> NewFunction(MaybeHandle<Object> maybe_prototype,
+ Handle<String> name,
+ InstanceType type,
+ int instance_size,
+ Handle<Code> code,
+ bool force_initial_map);
+ Handle<JSFunction> NewFunction(Handle<String> name,
+ InstanceType type,
+ int instance_size,
+ Handle<Code> code,
+ bool force_initial_map);
+
+ Handle<JSFunction> NewFunctionWithPrototype(Handle<String> name,
+ InstanceType type,
+ int instance_size,
+ Handle<JSObject> prototype,
+ Handle<Code> code,
+ bool force_initial_map);
+
+ // Create a serialized scope info.
Handle<ScopeInfo> NewScopeInfo(int length);
+ // Create an External object for V8's external API.
Handle<JSObject> NewExternal(void* value);
+ // The reference to the Code object is stored in self_reference.
+ // This allows generated code to reference its own Code object
+ // by containing this handle.
Handle<Code> NewCode(const CodeDesc& desc,
Code::Flags flags,
Handle<Object> self_reference,
@@ -434,10 +503,6 @@ class Factory {
Handle<Code> CopyCode(Handle<Code> code, Vector<byte> reloc_info);
- Handle<Object> ToObject(Handle<Object> object);
- Handle<Object> ToObject(Handle<Object> object,
- Handle<Context> native_context);
-
// Interface for creating error objects.
Handle<Object> NewError(const char* maker, const char* message,
@@ -459,6 +524,11 @@ class Factory {
Vector< Handle<Object> > args);
Handle<Object> NewRangeError(Handle<String> message);
+ Handle<Object> NewInvalidStringLengthError() {
+ return NewRangeError("invalid_string_length",
+ HandleVector<Object>(NULL, 0));
+ }
+
Handle<Object> NewSyntaxError(const char* message, Handle<JSArray> args);
Handle<Object> NewSyntaxError(Handle<String> message);
@@ -470,29 +540,14 @@ class Factory {
Handle<Object> NewEvalError(const char* message,
Vector< Handle<Object> > args);
+ Handle<JSObject> NewIteratorResultObject(Handle<Object> value, bool done);
- Handle<JSFunction> NewFunction(Handle<String> name,
- InstanceType type,
- int instance_size,
- Handle<Code> code,
- bool force_initial_map);
+ Handle<String> NumberToString(Handle<Object> number,
+ bool check_number_string_cache = true);
- Handle<JSFunction> NewFunction(Handle<Map> function_map,
- Handle<SharedFunctionInfo> shared, Handle<Object> prototype);
-
-
- Handle<JSFunction> NewFunctionWithPrototype(Handle<String> name,
- InstanceType type,
- int instance_size,
- Handle<JSObject> prototype,
- Handle<Code> code,
- bool force_initial_map);
-
- Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name,
- Handle<Code> code);
-
- Handle<String> NumberToString(Handle<Object> number);
- Handle<String> Uint32ToString(uint32_t value);
+ Handle<String> Uint32ToString(uint32_t value) {
+ return NumberToString(NewNumberFromUint(value));
+ }
enum ApiInstanceType {
JavaScriptObject,
@@ -502,6 +557,7 @@ class Factory {
Handle<JSFunction> CreateApiFunction(
Handle<FunctionTemplateInfo> data,
+ Handle<Object> prototype,
ApiInstanceType type = JavaScriptObject);
Handle<JSFunction> InstallMembers(Handle<JSFunction> function);
@@ -509,9 +565,8 @@ class Factory {
// Installs interceptors on the instance. 'desc' is a function template,
// and instance is an object instance created by the function of this
// function template.
- void ConfigureInstance(Handle<FunctionTemplateInfo> desc,
- Handle<JSObject> instance,
- bool* pending_exception);
+ MUST_USE_RESULT MaybeHandle<FunctionTemplateInfo> ConfigureInstance(
+ Handle<FunctionTemplateInfo> desc, Handle<JSObject> instance);
#define ROOT_ACCESSOR(type, name, camel_name) \
inline Handle<type> name() { \
@@ -537,18 +592,28 @@ class Factory {
INTERNALIZED_STRING_LIST(STRING_ACCESSOR)
#undef STRING_ACCESSOR
+ inline void set_string_table(Handle<StringTable> table) {
+ isolate()->heap()->set_string_table(*table);
+ }
+
Handle<String> hidden_string() {
return Handle<String>(&isolate()->heap()->hidden_string_);
}
+ // Allocates a new SharedFunctionInfo object.
Handle<SharedFunctionInfo> NewSharedFunctionInfo(
Handle<String> name,
int number_of_literals,
bool is_generator,
Handle<Code> code,
- Handle<ScopeInfo> scope_info);
+ Handle<ScopeInfo> scope_info,
+ Handle<FixedArray> feedback_vector);
Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name);
+ // Allocate a new type feedback vector
+ Handle<FixedArray> NewTypeFeedbackVector(int slot_count);
+
+ // Allocates a new JSMessageObject object.
Handle<JSMessageObject> NewJSMessageObject(
Handle<String> type,
Handle<JSArray> arguments,
@@ -557,19 +622,7 @@ class Factory {
Handle<Object> script,
Handle<Object> stack_frames);
- Handle<SeededNumberDictionary> DictionaryAtNumberPut(
- Handle<SeededNumberDictionary>,
- uint32_t key,
- Handle<Object> value);
-
- Handle<UnseededNumberDictionary> DictionaryAtNumberPut(
- Handle<UnseededNumberDictionary>,
- uint32_t key,
- Handle<Object> value);
-
-#ifdef ENABLE_DEBUGGER_SUPPORT
Handle<DebugInfo> NewDebugInfo(Handle<SharedFunctionInfo> shared);
-#endif
// Return a map using the map cache in the native context.
// The key the an ordered set of property names.
@@ -603,12 +656,33 @@ class Factory {
private:
Isolate* isolate() { return reinterpret_cast<Isolate*>(this); }
- Handle<JSFunction> NewFunctionHelper(Handle<String> name,
- Handle<Object> prototype);
-
- Handle<JSFunction> NewFunctionWithoutPrototypeHelper(
- Handle<String> name,
- StrictMode strict_mode);
+ // Creates a heap object based on the map. The fields of the heap object are
+ // not initialized by New<>() functions. It's the responsibility of the caller
+ // to do that.
+ template<typename T>
+ Handle<T> New(Handle<Map> map, AllocationSpace space);
+
+ template<typename T>
+ Handle<T> New(Handle<Map> map,
+ AllocationSpace space,
+ Handle<AllocationSite> allocation_site);
+
+ // Creates a code object that is not yet fully initialized yet.
+ inline Handle<Code> NewCodeRaw(int object_size, bool immovable);
+
+ // Initializes a function with a shared part and prototype.
+ // Note: this code was factored out of NewFunction such that other parts of
+ // the VM could use it. Specifically, a function that creates instances of
+ // type JS_FUNCTION_TYPE benefit from the use of this function.
+ inline void InitializeFunction(Handle<JSFunction> function,
+ Handle<SharedFunctionInfo> info,
+ Handle<Context> context);
+
+ // Creates a function initialized with a shared part.
+ inline Handle<JSFunction> NewFunction(Handle<Map> map,
+ Handle<SharedFunctionInfo> info,
+ Handle<Context> context,
+ PretenureFlag pretenure = TENURED);
// Create a new map cache.
Handle<MapCache> NewMapCache(int at_least_space_for);
@@ -617,19 +691,14 @@ class Factory {
Handle<MapCache> AddToMapCache(Handle<Context> context,
Handle<FixedArray> keys,
Handle<Map> map);
-};
+ // Attempt to find the number in a small cache. If we finds it, return
+ // the string representation of the number. Otherwise return undefined.
+ Handle<Object> GetNumberStringCache(Handle<Object> number);
-Handle<Object> Factory::NewNumberFromSize(size_t value,
- PretenureFlag pretenure) {
- if (Smi::IsValid(static_cast<intptr_t>(value))) {
- return Handle<Object>(Smi::FromIntptr(static_cast<intptr_t>(value)),
- isolate());
- } else {
- return NewNumber(static_cast<double>(value), pretenure);
- }
-}
-
+ // Update the cache with a new number-string pair.
+ void SetNumberStringCache(Handle<Object> number, Handle<String> string);
+};
} } // namespace v8::internal
diff --git a/deps/v8/src/fast-dtoa.cc b/deps/v8/src/fast-dtoa.cc
index e62bd01fbb..87ad2870dd 100644
--- a/deps/v8/src/fast-dtoa.cc
+++ b/deps/v8/src/fast-dtoa.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "../include/v8stdint.h"
#include "checks.h"
diff --git a/deps/v8/src/fast-dtoa.h b/deps/v8/src/fast-dtoa.h
index ef28557934..d96c296f15 100644
--- a/deps/v8/src/fast-dtoa.h
+++ b/deps/v8/src/fast-dtoa.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_FAST_DTOA_H_
#define V8_FAST_DTOA_H_
diff --git a/deps/v8/src/feedback-slots.h b/deps/v8/src/feedback-slots.h
index 9760c652bc..bc33a46076 100644
--- a/deps/v8/src/feedback-slots.h
+++ b/deps/v8/src/feedback-slots.h
@@ -1,29 +1,6 @@
// Copyright 2014 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_FEEDBACK_SLOTS_H_
#define V8_FEEDBACK_SLOTS_H_
@@ -35,76 +12,16 @@
namespace v8 {
namespace internal {
-enum ComputablePhase {
- DURING_PARSE,
- AFTER_SCOPING
-};
-
-
class FeedbackSlotInterface {
public:
static const int kInvalidFeedbackSlot = -1;
virtual ~FeedbackSlotInterface() {}
- // When can we ask how many feedback slots are necessary?
- virtual ComputablePhase GetComputablePhase() = 0;
- virtual int ComputeFeedbackSlotCount(Isolate* isolate) = 0;
+ virtual int ComputeFeedbackSlotCount() = 0;
virtual void SetFirstFeedbackSlot(int slot) = 0;
};
-
-class DeferredFeedbackSlotProcessor {
- public:
- DeferredFeedbackSlotProcessor()
- : slot_nodes_(NULL),
- slot_count_(0) { }
-
- void add_slot_node(Zone* zone, FeedbackSlotInterface* slot) {
- if (slot->GetComputablePhase() == DURING_PARSE) {
- // No need to add to the list
- int count = slot->ComputeFeedbackSlotCount(zone->isolate());
- slot->SetFirstFeedbackSlot(slot_count_);
- slot_count_ += count;
- } else {
- if (slot_nodes_ == NULL) {
- slot_nodes_ = new(zone) ZoneList<FeedbackSlotInterface*>(10, zone);
- }
- slot_nodes_->Add(slot, zone);
- }
- }
-
- void ProcessFeedbackSlots(Isolate* isolate) {
- // Scope analysis must have been done.
- if (slot_nodes_ == NULL) {
- return;
- }
-
- int current_slot = slot_count_;
- for (int i = 0; i < slot_nodes_->length(); i++) {
- FeedbackSlotInterface* slot_interface = slot_nodes_->at(i);
- int count = slot_interface->ComputeFeedbackSlotCount(isolate);
- if (count > 0) {
- slot_interface->SetFirstFeedbackSlot(current_slot);
- current_slot += count;
- }
- }
-
- slot_count_ = current_slot;
- slot_nodes_->Clear();
- }
-
- int slot_count() {
- ASSERT(slot_count_ >= 0);
- return slot_count_;
- }
-
- private:
- ZoneList<FeedbackSlotInterface*>* slot_nodes_;
- int slot_count_;
-};
-
-
} } // namespace v8::internal
#endif // V8_FEEDBACK_SLOTS_H_
diff --git a/deps/v8/src/fixed-dtoa.cc b/deps/v8/src/fixed-dtoa.cc
index fd90eca901..014f8ab869 100644
--- a/deps/v8/src/fixed-dtoa.cc
+++ b/deps/v8/src/fixed-dtoa.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <cmath>
diff --git a/deps/v8/src/fixed-dtoa.h b/deps/v8/src/fixed-dtoa.h
index 93f826fe84..b6495c11ef 100644
--- a/deps/v8/src/fixed-dtoa.h
+++ b/deps/v8/src/fixed-dtoa.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_FIXED_DTOA_H_
#define V8_FIXED_DTOA_H_
diff --git a/deps/v8/src/flag-definitions.h b/deps/v8/src/flag-definitions.h
index b93d03b59c..30cbcd7bc6 100644
--- a/deps/v8/src/flag-definitions.h
+++ b/deps/v8/src/flag-definitions.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file defines all of the flags. It is separated into different section,
// for Debug, Release, Logging and Profiling, etc. To add a new flag, find the
@@ -185,6 +162,7 @@ DEFINE_bool(harmony_numeric_literals, false,
DEFINE_bool(harmony_strings, false, "enable harmony string")
DEFINE_bool(harmony_arrays, false, "enable harmony arrays")
DEFINE_bool(harmony_maths, false, "enable harmony math functions")
+DEFINE_bool(harmony_promises, true, "(dummy flag, has no effect)")
DEFINE_bool(harmony, false, "enable all harmony features (except typeof)")
DEFINE_implication(harmony, harmony_scoping)
@@ -226,6 +204,9 @@ DEFINE_bool(track_computed_fields, true, "track computed boilerplate fields")
DEFINE_implication(track_double_fields, track_fields)
DEFINE_implication(track_heap_object_fields, track_fields)
DEFINE_implication(track_computed_fields, track_fields)
+DEFINE_bool(track_field_types, true, "track field types")
+DEFINE_implication(track_field_types, track_fields)
+DEFINE_implication(track_field_types, track_heap_object_fields)
DEFINE_bool(smi_binop, true, "support smi representation in binary operations")
// Flags for optimization types.
@@ -464,9 +445,6 @@ DEFINE_bool(trace_array_abuse, false,
"trace out-of-bounds accesses to all arrays")
DEFINE_implication(trace_array_abuse, trace_js_array_abuse)
DEFINE_implication(trace_array_abuse, trace_external_array_abuse)
-DEFINE_bool(debugger_auto_break, true,
- "automatically set the debug break flag when debugger commands are "
- "in the queue")
DEFINE_bool(enable_liveedit, true, "enable liveedit experimental feature")
DEFINE_bool(hard_abort, true, "abort by crashing")
@@ -485,8 +463,10 @@ DEFINE_bool(always_inline_smi_code, false,
"always inline smi code in non-opt code")
// heap.cc
-DEFINE_int(max_new_space_size, 0, "max size of the new generation (in kBytes)")
-DEFINE_int(max_old_space_size, 0, "max size of the old generation (in Mbytes)")
+DEFINE_int(max_new_space_size, 0,
+ "max size of the new space consisting of two semi-spaces which are half"
+ "the size (in MBytes)")
+DEFINE_int(max_old_space_size, 0, "max size of the old space (in Mbytes)")
DEFINE_int(max_executable_size, 0, "max size of executable memory (in Mbytes)")
DEFINE_bool(gc_global, false, "always perform global GCs")
DEFINE_int(gc_interval, -1, "garbage collect after <n> allocations")
@@ -511,6 +491,8 @@ DEFINE_bool(trace_external_memory, false,
"it is adjusted.")
DEFINE_bool(collect_maps, true,
"garbage collect maps from which no objects can be reached")
+DEFINE_bool(weak_embedded_maps_in_ic, true,
+ "make maps embedded in inline cache stubs")
DEFINE_bool(weak_embedded_maps_in_optimized_code, true,
"make maps embedded in optimized code weak")
DEFINE_bool(weak_embedded_objects_in_optimized_code, true,
@@ -529,8 +511,8 @@ DEFINE_bool(trace_incremental_marking, false,
"trace progress of the incremental marking")
DEFINE_bool(track_gc_object_stats, false,
"track object counts and memory usage")
-DEFINE_bool(parallel_sweeping, true, "enable parallel sweeping")
-DEFINE_bool(concurrent_sweeping, false, "enable concurrent sweeping")
+DEFINE_bool(parallel_sweeping, false, "enable parallel sweeping")
+DEFINE_bool(concurrent_sweeping, true, "enable concurrent sweeping")
DEFINE_int(sweeper_threads, 0,
"number of parallel and concurrent sweeping threads")
DEFINE_bool(job_based_sweeping, false, "enable job based sweeping")
@@ -556,8 +538,6 @@ DEFINE_bool(native_code_counters, false,
// mark-compact.cc
DEFINE_bool(always_compact, false, "Perform compaction on every full GC")
-DEFINE_bool(lazy_sweeping, true,
- "Use lazy sweeping for old pointer and data spaces")
DEFINE_bool(never_compact, false,
"Never perform compaction on full GC - testing only")
DEFINE_bool(compact_code_space, true,
@@ -644,7 +624,13 @@ DEFINE_string(testing_serialization_file, "/tmp/serdes",
// mksnapshot.cc
DEFINE_string(extra_code, NULL, "A filename with extra code to be included in"
- " the snapshot (mksnapshot only)")
+ " the snapshot (mksnapshot only)")
+DEFINE_string(raw_file, NULL, "A file to write the raw snapshot bytes to. "
+ "(mksnapshot only)")
+DEFINE_string(raw_context_file, NULL, "A file to write the raw context "
+ "snapshot bytes to. (mksnapshot only)")
+DEFINE_bool(omit, false, "Omit raw snapshot bytes in generated code. "
+ "(mksnapshot only)")
// code-stubs-hydrogen.cc
DEFINE_bool(profile_hydrogen_code_stub_compilation, false,
@@ -664,13 +650,11 @@ DEFINE_neg_implication(predictable, parallel_sweeping)
DEFINE_bool(help, false, "Print usage message, including flags, on console")
DEFINE_bool(dump_counters, false, "Dump counters on exit")
-#ifdef ENABLE_DEBUGGER_SUPPORT
DEFINE_bool(debugger, false, "Enable JavaScript debugger")
DEFINE_bool(remote_debugger, false, "Connect JavaScript debugger to the "
"debugger agent in another process")
DEFINE_bool(debugger_agent, false, "Enable debugger agent")
DEFINE_int(debugger_port, 5858, "Port to use for remote debugging")
-#endif // ENABLE_DEBUGGER_SUPPORT
DEFINE_string(map_counters, "", "Map counters to a file")
DEFINE_args(js_arguments,
@@ -739,7 +723,6 @@ DEFINE_bool(print_scopes, false, "print scopes")
DEFINE_bool(trace_contexts, false, "trace contexts operations")
// heap.cc
-DEFINE_bool(gc_greedy, false, "perform GC prior to some allocations")
DEFINE_bool(gc_verbose, false, "print stuff during garbage collection")
DEFINE_bool(heap_stats, false, "report heap statistics before and after GC")
DEFINE_bool(code_stats, false, "report code statistics after GC")
@@ -787,7 +770,6 @@ DEFINE_bool(trace_regexp_assembler, false,
DEFINE_bool(log, false,
"Minimal logging (no API, code, GC, suspect, or handles samples).")
DEFINE_bool(log_all, false, "Log all events to the log file.")
-DEFINE_bool(log_runtime, false, "Activate runtime system %Log call.")
DEFINE_bool(log_api, false, "Log API events to the log file.")
DEFINE_bool(log_code, false,
"Log code events to the log file without profiling.")
diff --git a/deps/v8/src/flags.cc b/deps/v8/src/flags.cc
index 8e42206c59..19a10e4165 100644
--- a/deps/v8/src/flags.cc
+++ b/deps/v8/src/flags.cc
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <ctype.h>
#include <stdlib.h>
@@ -360,10 +337,15 @@ static Flag* FindFlag(const char* name) {
}
+bool FlagList::serializer_enabled_ = false;
+
+
// static
int FlagList::SetFlagsFromCommandLine(int* argc,
char** argv,
- bool remove_flags) {
+ bool remove_flags,
+ bool serializer_enabled) {
+ serializer_enabled_ = serializer_enabled;
int return_code = 0;
// parse arguments
for (int i = 1; i < *argc;) {
@@ -545,7 +527,7 @@ void FlagList::ResetAllFlags() {
void FlagList::PrintHelp() {
#if V8_TARGET_ARCH_ARM
CpuFeatures::PrintTarget();
- CpuFeatures::Probe();
+ CpuFeatures::Probe(serializer_enabled_);
CpuFeatures::PrintFeatures();
#endif // V8_TARGET_ARCH_ARM
diff --git a/deps/v8/src/flags.h b/deps/v8/src/flags.h
index fe182e5221..df786d7c33 100644
--- a/deps/v8/src/flags.h
+++ b/deps/v8/src/flags.h
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_FLAGS_H_
#define V8_FLAGS_H_
@@ -63,7 +40,10 @@ class FlagList {
// --flag=value (non-bool flags only, no spaces around '=')
// --flag value (non-bool flags only)
// -- (equivalent to --js_arguments, captures all remaining args)
- static int SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags);
+ static int SetFlagsFromCommandLine(int* argc,
+ char** argv,
+ bool remove_flags,
+ bool serializer_enabled = false);
// Set the flag values by parsing the string str. Splits string into argc
// substrings argv[], each of which consisting of non-white-space chars,
@@ -78,6 +58,10 @@ class FlagList {
// Set flags as consequence of being implied by another flag.
static void EnforceFlagImplications();
+
+ private:
+ // TODO(svenpanne) Remove this when Serializer/startup has been refactored.
+ static bool serializer_enabled_;
};
} } // namespace v8::internal
diff --git a/deps/v8/src/frames-inl.h b/deps/v8/src/frames-inl.h
index aacb5664a2..9b5d4dbb96 100644
--- a/deps/v8/src/frames-inl.h
+++ b/deps/v8/src/frames-inl.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_FRAMES_INL_H_
#define V8_FRAMES_INL_H_
diff --git a/deps/v8/src/frames.cc b/deps/v8/src/frames.cc
index 0c47de910d..e7c2a149ea 100644
--- a/deps/v8/src/frames.cc
+++ b/deps/v8/src/frames.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -663,7 +640,7 @@ void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
// Skip saved double registers.
if (safepoint_entry.has_doubles()) {
// Number of doubles not known at snapshot time.
- ASSERT(!Serializer::enabled());
+ ASSERT(!Serializer::enabled(isolate()));
parameters_base += DoubleRegister::NumAllocatableRegisters() *
kDoubleSize / kPointerSize;
}
@@ -806,7 +783,6 @@ void JavaScriptFrame::PrintTop(Isolate* isolate,
bool print_args,
bool print_line_number) {
// constructor calls
- HandleScope scope(isolate);
DisallowHeapAllocation no_allocation;
JavaScriptFrameIterator it(isolate);
while (!it.done()) {
@@ -827,8 +803,8 @@ void JavaScriptFrame::PrintTop(Isolate* isolate,
int source_pos = code->SourcePosition(pc);
Object* maybe_script = shared->script();
if (maybe_script->IsScript()) {
- Handle<Script> script(Script::cast(maybe_script));
- int line = GetScriptLineNumberSafe(script, source_pos) + 1;
+ Script* script = Script::cast(maybe_script);
+ int line = script->GetLineNumber(source_pos) + 1;
Object* script_name_raw = script->name();
if (script_name_raw->IsString()) {
String* script_name = String::cast(script->name());
@@ -991,13 +967,10 @@ void OptimizedFrame::Summarize(List<FrameSummary>* frames) {
it.Next(); // Skip height.
// The translation commands are ordered and the receiver is always
- // at the first position. Since we are always at a call when we need
- // to construct a stack trace, the receiver is always in a stack slot.
+ // at the first position.
+ // If we are at a call, the receiver is always in a stack slot.
+ // Otherwise we are not guaranteed to get the receiver value.
opcode = static_cast<Translation::Opcode>(it.Next());
- ASSERT(opcode == Translation::STACK_SLOT ||
- opcode == Translation::LITERAL ||
- opcode == Translation::CAPTURED_OBJECT ||
- opcode == Translation::DUPLICATED_OBJECT);
int index = it.Next();
// Get the correct receiver in the optimized frame.
@@ -1021,6 +994,7 @@ void OptimizedFrame::Summarize(List<FrameSummary>* frames) {
: this->GetParameter(parameter_index);
}
} else {
+ // The receiver is not in a stack slot nor in a literal. We give up.
// TODO(3029): Materializing a captured object (or duplicated
// object) is hard, we return undefined for now. This breaks the
// produced stack trace, as constructor frames aren't marked as
@@ -1171,7 +1145,7 @@ void StackFrame::PrintIndex(StringStream* accumulator,
void JavaScriptFrame::Print(StringStream* accumulator,
PrintMode mode,
int index) const {
- HandleScope scope(isolate());
+ DisallowHeapAllocation no_gc;
Object* receiver = this->receiver();
JSFunction* function = this->function();
@@ -1185,13 +1159,11 @@ void JavaScriptFrame::Print(StringStream* accumulator,
// doesn't contain scope info, scope_info will return 0 for the number of
// parameters, stack local variables, context local variables, stack slots,
// or context slots.
- Handle<ScopeInfo> scope_info(ScopeInfo::Empty(isolate()));
-
- Handle<SharedFunctionInfo> shared(function->shared());
- scope_info = Handle<ScopeInfo>(shared->scope_info());
+ SharedFunctionInfo* shared = function->shared();
+ ScopeInfo* scope_info = shared->scope_info();
Object* script_obj = shared->script();
if (script_obj->IsScript()) {
- Handle<Script> script(Script::cast(script_obj));
+ Script* script = Script::cast(script_obj);
accumulator->Add(" [");
accumulator->PrintName(script->name());
@@ -1199,11 +1171,11 @@ void JavaScriptFrame::Print(StringStream* accumulator,
if (code != NULL && code->kind() == Code::FUNCTION &&
pc >= code->instruction_start() && pc < code->instruction_end()) {
int source_pos = code->SourcePosition(pc);
- int line = GetScriptLineNumberSafe(script, source_pos) + 1;
+ int line = script->GetLineNumber(source_pos) + 1;
accumulator->Add(":%d", line);
} else {
int function_start_pos = shared->start_position();
- int line = GetScriptLineNumberSafe(script, function_start_pos) + 1;
+ int line = script->GetLineNumber(function_start_pos) + 1;
accumulator->Add(":~%d", line);
}
@@ -1406,14 +1378,14 @@ Address StubFailureTrampolineFrame::GetCallerStackPointer() const {
Code* StubFailureTrampolineFrame::unchecked_code() const {
Code* trampoline;
- StubFailureTrampolineStub(NOT_JS_FUNCTION_STUB_MODE).
- FindCodeInCache(&trampoline, isolate());
+ StubFailureTrampolineStub(isolate(), NOT_JS_FUNCTION_STUB_MODE).
+ FindCodeInCache(&trampoline);
if (trampoline->contains(pc())) {
return trampoline;
}
- StubFailureTrampolineStub(JS_FUNCTION_STUB_MODE).
- FindCodeInCache(&trampoline, isolate());
+ StubFailureTrampolineStub(isolate(), JS_FUNCTION_STUB_MODE).
+ FindCodeInCache(&trampoline);
if (trampoline->contains(pc())) {
return trampoline;
}
diff --git a/deps/v8/src/frames.h b/deps/v8/src/frames.h
index 17f0cb35ab..3dd6e93681 100644
--- a/deps/v8/src/frames.h
+++ b/deps/v8/src/frames.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_FRAMES_H_
#define V8_FRAMES_H_
diff --git a/deps/v8/src/full-codegen.cc b/deps/v8/src/full-codegen.cc
index fa9ecf41bc..2846d2ba14 100644
--- a/deps/v8/src/full-codegen.cc
+++ b/deps/v8/src/full-codegen.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -347,9 +324,7 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
cgen.PopulateTypeFeedbackInfo(code);
code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
code->set_handler_table(*cgen.handler_table());
-#ifdef ENABLE_DEBUGGER_SUPPORT
code->set_compiled_optimizable(info->IsOptimizable());
-#endif // ENABLE_DEBUGGER_SUPPORT
code->set_allow_osr_at_loop_nesting_level(0);
code->set_profiler_ticks(0);
code->set_back_edge_table_offset(table_offset);
@@ -386,14 +361,12 @@ unsigned FullCodeGenerator::EmitBackEdgeTable() {
}
-void FullCodeGenerator::InitializeFeedbackVector() {
- int length = info_->function()->slot_count();
- feedback_vector_ = isolate()->factory()->NewFixedArray(length, TENURED);
- Handle<Object> sentinel = TypeFeedbackInfo::UninitializedSentinel(isolate());
- // Ensure that it's safe to set without using a write barrier.
- ASSERT_EQ(isolate()->heap()->uninitialized_symbol(), *sentinel);
- for (int i = 0; i < length; i++) {
- feedback_vector_->set(i, *sentinel, SKIP_WRITE_BARRIER);
+void FullCodeGenerator::EnsureSlotContainsAllocationSite(int slot) {
+ Handle<FixedArray> vector = FeedbackVector();
+ if (!vector->get(slot)->IsAllocationSite()) {
+ Handle<AllocationSite> allocation_site =
+ isolate()->factory()->NewAllocationSite();
+ vector->set(slot, *allocation_site);
}
}
@@ -403,8 +376,8 @@ void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty());
if (!info_->HasDeoptimizationSupport()) return;
int length = bailout_entries_.length();
- Handle<DeoptimizationOutputData> data = isolate()->factory()->
- NewDeoptimizationOutputData(length, TENURED);
+ Handle<DeoptimizationOutputData> data =
+ DeoptimizationOutputData::New(isolate(), length, TENURED);
for (int i = 0; i < length; i++) {
data->SetAstId(i, bailout_entries_[i].id);
data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state));
@@ -416,24 +389,23 @@ void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo();
info->set_ic_total_count(ic_total_count_);
- info->set_feedback_vector(*FeedbackVector());
ASSERT(!isolate()->heap()->InNewSpace(*info));
code->set_type_feedback_info(*info);
}
void FullCodeGenerator::Initialize() {
+ InitializeAstVisitor(info_->zone());
// The generation of debug code must match between the snapshot code and the
// code that is generated later. This is assumed by the debugger when it is
// calculating PC offsets after generating a debug version of code. Therefore
// we disable the production of debug code in the full compiler if we are
// either generating a snapshot or we booted from a snapshot.
generate_debug_code_ = FLAG_debug_code &&
- !Serializer::enabled() &&
+ !Serializer::enabled(isolate()) &&
!Snapshot::HaveASnapshotToStartFrom();
masm_->set_emit_debug_code(generate_debug_code_);
masm_->set_predictable_code_size(true);
- InitializeAstVisitor(info_->zone());
}
@@ -833,7 +805,6 @@ void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
-#ifdef ENABLE_DEBUGGER_SUPPORT
if (!isolate()->debugger()->IsDebuggerActive()) {
CodeGenerator::RecordPositions(masm_, stmt->position());
} else {
@@ -852,14 +823,10 @@ void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
Debug::GenerateSlot(masm_);
}
}
-#else
- CodeGenerator::RecordPositions(masm_, stmt->position());
-#endif
}
void FullCodeGenerator::SetExpressionPosition(Expression* expr) {
-#ifdef ENABLE_DEBUGGER_SUPPORT
if (!isolate()->debugger()->IsDebuggerActive()) {
CodeGenerator::RecordPositions(masm_, expr->position());
} else {
@@ -882,9 +849,6 @@ void FullCodeGenerator::SetExpressionPosition(Expression* expr) {
Debug::GenerateSlot(masm_);
}
}
-#else
- CodeGenerator::RecordPositions(masm_, expr->position());
-#endif
}
@@ -1506,13 +1470,11 @@ void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
-#ifdef ENABLE_DEBUGGER_SUPPORT
Comment cmnt(masm_, "[ DebuggerStatement");
SetStatementPosition(stmt);
__ DebugBreak();
// Ignore the return value.
-#endif
}
@@ -1589,8 +1551,10 @@ void FullCodeGenerator::VisitNativeFunctionLiteral(
Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
bool is_generator = false;
Handle<SharedFunctionInfo> shared =
- isolate()->factory()->NewSharedFunctionInfo(name, literals, is_generator,
- code, Handle<ScopeInfo>(fun->shared()->scope_info()));
+ isolate()->factory()->NewSharedFunctionInfo(
+ name, literals, is_generator,
+ code, Handle<ScopeInfo>(fun->shared()->scope_info()),
+ Handle<FixedArray>(fun->shared()->feedback_vector()));
shared->set_construct_stub(*construct_stub);
// Copy the function data to the shared function info.
diff --git a/deps/v8/src/full-codegen.h b/deps/v8/src/full-codegen.h
index 0d0a6ffedc..167538ed9c 100644
--- a/deps/v8/src/full-codegen.h
+++ b/deps/v8/src/full-codegen.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_FULL_CODEGEN_H_
#define V8_FULL_CODEGEN_H_
@@ -122,16 +99,21 @@ class FullCodeGenerator: public AstVisitor {
// Platform-specific code size multiplier.
#if V8_TARGET_ARCH_IA32
- static const int kCodeSizeMultiplier = 100;
+ static const int kCodeSizeMultiplier = 105;
+ static const int kBootCodeSizeMultiplier = 100;
#elif V8_TARGET_ARCH_X64
- static const int kCodeSizeMultiplier = 162;
+ static const int kCodeSizeMultiplier = 170;
+ static const int kBootCodeSizeMultiplier = 140;
#elif V8_TARGET_ARCH_ARM
- static const int kCodeSizeMultiplier = 142;
+ static const int kCodeSizeMultiplier = 149;
+ static const int kBootCodeSizeMultiplier = 110;
#elif V8_TARGET_ARCH_ARM64
// TODO(all): Copied ARM value. Check this is sensible for ARM64.
- static const int kCodeSizeMultiplier = 142;
+ static const int kCodeSizeMultiplier = 149;
+ static const int kBootCodeSizeMultiplier = 110;
#elif V8_TARGET_ARCH_MIPS
- static const int kCodeSizeMultiplier = 142;
+ static const int kCodeSizeMultiplier = 149;
+ static const int kBootCodeSizeMultiplier = 120;
#else
#error Unsupported target architecture.
#endif
@@ -437,12 +419,9 @@ class FullCodeGenerator: public AstVisitor {
// Feedback slot support. The feedback vector will be cleared during gc and
// collected by the type-feedback oracle.
Handle<FixedArray> FeedbackVector() {
- return feedback_vector_;
+ return info_->feedback_vector();
}
- void StoreFeedbackVectorSlot(int slot, Handle<Object> object) {
- feedback_vector_->set(slot, *object);
- }
- void InitializeFeedbackVector();
+ void EnsureSlotContainsAllocationSite(int slot);
// Record a call's return site offset, used to rebuild the frame if the
// called function was inlined at the site.
@@ -485,9 +464,9 @@ class FullCodeGenerator: public AstVisitor {
void EmitReturnSequence();
// Platform-specific code sequences for calls
- void EmitCallWithStub(Call* expr);
- void EmitCallWithIC(Call* expr);
- void EmitKeyedCallWithIC(Call* expr, Expression* key);
+ void EmitCall(Call* expr, CallIC::CallType = CallIC::FUNCTION);
+ void EmitCallWithLoadIC(Call* expr);
+ void EmitKeyedCallWithLoadIC(Call* expr, Expression* key);
// Platform-specific code for inline runtime calls.
InlineFunctionGenerator FindInlineFunctionGenerator(Runtime::FunctionId id);
@@ -844,7 +823,6 @@ class FullCodeGenerator: public AstVisitor {
ZoneList<BackEdgeEntry> back_edges_;
int ic_total_count_;
Handle<FixedArray> handler_table_;
- Handle<FixedArray> feedback_vector_;
Handle<Cell> profiling_counter_;
bool generate_debug_code_;
diff --git a/deps/v8/src/func-name-inferrer.cc b/deps/v8/src/func-name-inferrer.cc
index 441113b7d8..370d6264df 100644
--- a/deps/v8/src/func-name-inferrer.cc
+++ b/deps/v8/src/func-name-inferrer.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -55,14 +32,16 @@ void FuncNameInferrer::PushEnclosingName(Handle<String> name) {
void FuncNameInferrer::PushLiteralName(Handle<String> name) {
- if (IsOpen() && !isolate()->heap()->prototype_string()->Equals(*name)) {
+ if (IsOpen() &&
+ !String::Equals(isolate()->factory()->prototype_string(), name)) {
names_stack_.Add(Name(name, kLiteralName), zone());
}
}
void FuncNameInferrer::PushVariableName(Handle<String> name) {
- if (IsOpen() && !isolate()->heap()->dot_result_string()->Equals(*name)) {
+ if (IsOpen() &&
+ !String::Equals(isolate()->factory()->dot_result_string(), name)) {
names_stack_.Add(Name(name, kVariableName), zone());
}
}
@@ -86,10 +65,9 @@ Handle<String> FuncNameInferrer::MakeNameFromStackHelper(int pos,
Handle<String> name = names_stack_.at(pos).name;
if (prev->length() + name->length() + 1 > String::kMaxLength) return prev;
Factory* factory = isolate()->factory();
- Handle<String> curr = factory->NewConsString(factory->dot_string(), name);
- CHECK_NOT_EMPTY_HANDLE(isolate(), curr);
- curr = factory->NewConsString(prev, curr);
- CHECK_NOT_EMPTY_HANDLE(isolate(), curr);
+ Handle<String> curr =
+ factory->NewConsString(factory->dot_string(), name).ToHandleChecked();
+ curr = factory->NewConsString(prev, curr).ToHandleChecked();
return MakeNameFromStackHelper(pos + 1, curr);
} else {
return MakeNameFromStackHelper(pos + 1, names_stack_.at(pos).name);
diff --git a/deps/v8/src/func-name-inferrer.h b/deps/v8/src/func-name-inferrer.h
index 41953ffed9..f0fdbd22e0 100644
--- a/deps/v8/src/func-name-inferrer.h
+++ b/deps/v8/src/func-name-inferrer.h
@@ -1,29 +1,6 @@
// Copyright 2006-2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_FUNC_NAME_INFERRER_H_
#define V8_FUNC_NAME_INFERRER_H_
diff --git a/deps/v8/src/gdb-jit.cc b/deps/v8/src/gdb-jit.cc
index afe5b7117d..f2861c15f3 100644
--- a/deps/v8/src/gdb-jit.cc
+++ b/deps/v8/src/gdb-jit.cc
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifdef ENABLE_GDB_JIT_INTERFACE
#include "v8.h"
@@ -252,8 +229,8 @@ class MachOSection : public DebugSectionBase<MachOSectionHeader> {
segment_(segment),
align_(align),
flags_(flags) {
- ASSERT(IsPowerOf2(align));
if (align_ != 0) {
+ ASSERT(IsPowerOf2(align));
align_ = WhichPowerOf2(align_);
}
}
@@ -1002,7 +979,7 @@ class CodeDescription BASE_EMBEDDED {
}
int GetScriptLineNumber(int pos) {
- return GetScriptLineNumberSafe(script_, pos) + 1;
+ return script_->GetLineNumber(pos) + 1;
}
@@ -1841,7 +1818,7 @@ extern "C" {
JITDescriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
#ifdef OBJECT_PRINT
- void __gdb_print_v8_object(MaybeObject* object) {
+ void __gdb_print_v8_object(Object* object) {
object->Print();
PrintF(stdout, "\n");
}
@@ -2003,8 +1980,7 @@ void GDBJITInterface::AddCode(Handle<Name> name,
CompilationInfo* info) {
if (!FLAG_gdbjit) return;
- // Force initialization of line_ends array.
- GetScriptLineNumber(script, 0);
+ Script::InitLineEnds(script);
if (!name.is_null() && name->IsString()) {
SmartArrayPointer<char> name_cstring =
diff --git a/deps/v8/src/gdb-jit.h b/deps/v8/src/gdb-jit.h
index bc1a8f3646..a961740001 100644
--- a/deps/v8/src/gdb-jit.h
+++ b/deps/v8/src/gdb-jit.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_GDB_JIT_H_
#define V8_GDB_JIT_H_
diff --git a/deps/v8/src/generator.js b/deps/v8/src/generator.js
index 3c8ea6f319..c152e3a6ee 100644
--- a/deps/v8/src/generator.js
+++ b/deps/v8/src/generator.js
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
"use strict";
diff --git a/deps/v8/src/global-handles.cc b/deps/v8/src/global-handles.cc
index e06f794828..d6cd479181 100644
--- a/deps/v8/src/global-handles.cc
+++ b/deps/v8/src/global-handles.cc
@@ -1,29 +1,6 @@
// Copyright 2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/global-handles.h b/deps/v8/src/global-handles.h
index 13fc111d81..210c0565c0 100644
--- a/deps/v8/src/global-handles.h
+++ b/deps/v8/src/global-handles.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_GLOBAL_HANDLES_H_
#define V8_GLOBAL_HANDLES_H_
@@ -33,7 +10,7 @@
#include "handles.h"
#include "list.h"
-#include "v8utils.h"
+#include "utils.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/src/globals.h b/deps/v8/src/globals.h
index db666d804b..5b4be2a6dc 100644
--- a/deps/v8/src/globals.h
+++ b/deps/v8/src/globals.h
@@ -1,35 +1,14 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_GLOBALS_H_
#define V8_GLOBALS_H_
#include "../include/v8stdint.h"
+#include "base/macros.h"
+
// Unfortunately, the INFINITY macro cannot be used with the '-pedantic'
// warning flag and certain versions of GCC due to a bug:
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11931
@@ -78,7 +57,7 @@ namespace internal {
#elif defined(__ARMEL__)
#define V8_HOST_ARCH_ARM 1
#define V8_HOST_ARCH_32_BIT 1
-#elif defined(__MIPSEL__)
+#elif defined(__MIPSEB__) || defined(__MIPSEL__)
#define V8_HOST_ARCH_MIPS 1
#define V8_HOST_ARCH_32_BIT 1
#else
@@ -108,7 +87,7 @@ namespace internal {
#define V8_TARGET_ARCH_ARM64 1
#elif defined(__ARMEL__)
#define V8_TARGET_ARCH_ARM 1
-#elif defined(__MIPSEL__)
+#elif defined(__MIPSEB__) || defined(__MIPSEL__)
#define V8_TARGET_ARCH_MIPS 1
#else
#error Target architecture was not detected as supported by v8
@@ -147,7 +126,7 @@ namespace internal {
#endif
#endif
-// Determine architecture endiannes (we only support little-endian).
+// Determine architecture endianness.
#if V8_TARGET_ARCH_IA32
#define V8_TARGET_LITTLE_ENDIAN 1
#elif V8_TARGET_ARCH_X64
@@ -157,9 +136,13 @@ namespace internal {
#elif V8_TARGET_ARCH_ARM64
#define V8_TARGET_LITTLE_ENDIAN 1
#elif V8_TARGET_ARCH_MIPS
+#if defined(__MIPSEB__)
+#define V8_TARGET_BIG_ENDIAN 1
+#else
#define V8_TARGET_LITTLE_ENDIAN 1
+#endif
#else
-#error Unknown target architecture endiannes
+#error Unknown target architecture endianness
#endif
// Determine whether the architecture uses an out-of-line constant pool.
@@ -316,25 +299,6 @@ const int kUC16Size = sizeof(uc16); // NOLINT
#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
-// The expression OFFSET_OF(type, field) computes the byte-offset
-// of the specified field relative to the containing type. This
-// corresponds to 'offsetof' (in stddef.h), except that it doesn't
-// use 0 or NULL, which causes a problem with the compiler warnings
-// we have enabled (which is also why 'offsetof' doesn't seem to work).
-// Here we simply use the non-zero value 4, which seems to work.
-#define OFFSET_OF(type, field) \
- (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4)
-
-
-// The expression ARRAY_SIZE(a) is a compile-time constant of type
-// size_t which represents the number of elements of the given
-// array. You should only use ARRAY_SIZE on statically allocated
-// arrays.
-#define ARRAY_SIZE(a) \
- ((sizeof(a) / sizeof(*(a))) / \
- static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
-
-
// The USE(x) template is used to silence C++ compiler warnings
// issued for (yet) unused variables (typically parameters).
template <typename T>
@@ -354,52 +318,6 @@ F FUNCTION_CAST(Address addr) {
}
-// A macro to disallow the evil copy constructor and operator= functions
-// This should be used in the private: declarations for a class
-#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
- TypeName(const TypeName&) V8_DELETE; \
- void operator=(const TypeName&) V8_DELETE
-
-
-// A macro to disallow all the implicit constructors, namely the
-// default constructor, copy constructor and operator= functions.
-//
-// This should be used in the private: declarations for a class
-// that wants to prevent anyone from instantiating it. This is
-// especially useful for classes containing only static methods.
-#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
- TypeName() V8_DELETE; \
- DISALLOW_COPY_AND_ASSIGN(TypeName)
-
-
-// Newly written code should use V8_INLINE and V8_NOINLINE directly.
-#define INLINE(declarator) V8_INLINE declarator
-#define NO_INLINE(declarator) V8_NOINLINE declarator
-
-
-// Newly written code should use V8_WARN_UNUSED_RESULT.
-#define MUST_USE_RESULT V8_WARN_UNUSED_RESULT
-
-
-// Define DISABLE_ASAN macros.
-#if defined(__has_feature)
-#if __has_feature(address_sanitizer)
-#define DISABLE_ASAN __attribute__((no_sanitize_address))
-#endif
-#endif
-
-
-#ifndef DISABLE_ASAN
-#define DISABLE_ASAN
-#endif
-
-#if V8_CC_GNU
-#define V8_IMMEDIATE_CRASH() __builtin_trap()
-#else
-#define V8_IMMEDIATE_CRASH() ((void(*)())0)()
-#endif
-
-
// -----------------------------------------------------------------------------
// Forward declarations for frequently used classes
// (sorted alphabetically)
diff --git a/deps/v8/src/handles-inl.h b/deps/v8/src/handles-inl.h
index a25b4a2266..d9f8c69c1b 100644
--- a/deps/v8/src/handles-inl.h
+++ b/deps/v8/src/handles-inl.h
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
//
#ifndef V8_HANDLES_INL_H_
@@ -39,40 +16,36 @@ namespace internal {
template<typename T>
Handle<T>::Handle(T* obj) {
- ASSERT(!obj->IsFailure());
location_ = HandleScope::CreateHandle(obj->GetIsolate(), obj);
}
template<typename T>
Handle<T>::Handle(T* obj, Isolate* isolate) {
- ASSERT(!obj->IsFailure());
location_ = HandleScope::CreateHandle(isolate, obj);
}
template <typename T>
-inline bool Handle<T>::is_identical_to(const Handle<T> other) const {
- ASSERT(location_ == NULL || !(*location_)->IsFailure());
- if (location_ == other.location_) return true;
- if (location_ == NULL || other.location_ == NULL) return false;
+inline bool Handle<T>::is_identical_to(const Handle<T> o) const {
// Dereferencing deferred handles to check object equality is safe.
- SLOW_ASSERT(IsDereferenceAllowed(NO_DEFERRED_CHECK) &&
- other.IsDereferenceAllowed(NO_DEFERRED_CHECK));
- return *location_ == *other.location_;
+ SLOW_ASSERT(
+ (location_ == NULL || IsDereferenceAllowed(NO_DEFERRED_CHECK)) &&
+ (o.location_ == NULL || o.IsDereferenceAllowed(NO_DEFERRED_CHECK)));
+ if (location_ == o.location_) return true;
+ if (location_ == NULL || o.location_ == NULL) return false;
+ return *location_ == *o.location_;
}
template <typename T>
inline T* Handle<T>::operator*() const {
- ASSERT(location_ != NULL && !(*location_)->IsFailure());
SLOW_ASSERT(IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK));
return *BitCast<T**>(location_);
}
template <typename T>
inline T** Handle<T>::location() const {
- ASSERT(location_ == NULL || !(*location_)->IsFailure());
SLOW_ASSERT(location_ == NULL ||
IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK));
return location_;
diff --git a/deps/v8/src/handles.cc b/deps/v8/src/handles.cc
index 398a68265c..89e034e9d4 100644
--- a/deps/v8/src/handles.cc
+++ b/deps/v8/src/handles.cc
@@ -1,45 +1,10 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
-#include "accessors.h"
-#include "api.h"
-#include "arguments.h"
-#include "bootstrapper.h"
-#include "compiler.h"
-#include "debug.h"
-#include "execution.h"
-#include "global-handles.h"
-#include "natives.h"
-#include "runtime.h"
-#include "string-search.h"
-#include "stub-cache.h"
-#include "vm-state-inl.h"
+#include "handles.h"
namespace v8 {
namespace internal {
@@ -124,605 +89,6 @@ Address HandleScope::current_limit_address(Isolate* isolate) {
}
-Handle<FixedArray> AddKeysFromJSArray(Handle<FixedArray> content,
- Handle<JSArray> array) {
- CALL_HEAP_FUNCTION(content->GetIsolate(),
- content->AddKeysFromJSArray(*array), FixedArray);
-}
-
-
-Handle<FixedArray> UnionOfKeys(Handle<FixedArray> first,
- Handle<FixedArray> second) {
- CALL_HEAP_FUNCTION(first->GetIsolate(),
- first->UnionOfKeys(*second), FixedArray);
-}
-
-
-Handle<JSGlobalProxy> ReinitializeJSGlobalProxy(
- Handle<JSFunction> constructor,
- Handle<JSGlobalProxy> global) {
- CALL_HEAP_FUNCTION(
- constructor->GetIsolate(),
- constructor->GetHeap()->ReinitializeJSGlobalProxy(*constructor, *global),
- JSGlobalProxy);
-}
-
-
-void FlattenString(Handle<String> string) {
- CALL_HEAP_FUNCTION_VOID(string->GetIsolate(), string->TryFlatten());
-}
-
-
-Handle<String> FlattenGetString(Handle<String> string) {
- CALL_HEAP_FUNCTION(string->GetIsolate(), string->TryFlatten(), String);
-}
-
-
-Handle<Object> ForceSetProperty(Handle<JSObject> object,
- Handle<Object> key,
- Handle<Object> value,
- PropertyAttributes attributes) {
- return Runtime::ForceSetObjectProperty(object->GetIsolate(), object, key,
- value, attributes);
-}
-
-
-Handle<Object> DeleteProperty(Handle<JSObject> object, Handle<Object> key) {
- Isolate* isolate = object->GetIsolate();
- CALL_HEAP_FUNCTION(isolate,
- Runtime::DeleteObjectProperty(
- isolate, object, key, JSReceiver::NORMAL_DELETION),
- Object);
-}
-
-
-Handle<Object> ForceDeleteProperty(Handle<JSObject> object,
- Handle<Object> key) {
- Isolate* isolate = object->GetIsolate();
- CALL_HEAP_FUNCTION(isolate,
- Runtime::DeleteObjectProperty(
- isolate, object, key, JSReceiver::FORCE_DELETION),
- Object);
-}
-
-
-Handle<Object> HasProperty(Handle<JSReceiver> obj, Handle<Object> key) {
- Isolate* isolate = obj->GetIsolate();
- CALL_HEAP_FUNCTION(isolate,
- Runtime::HasObjectProperty(isolate, obj, key), Object);
-}
-
-
-Handle<Object> GetProperty(Handle<JSReceiver> obj,
- const char* name) {
- Isolate* isolate = obj->GetIsolate();
- Handle<String> str = isolate->factory()->InternalizeUtf8String(name);
- CALL_HEAP_FUNCTION(isolate, obj->GetProperty(*str), Object);
-}
-
-
-Handle<Object> GetProperty(Isolate* isolate,
- Handle<Object> obj,
- Handle<Object> key) {
- CALL_HEAP_FUNCTION(isolate,
- Runtime::GetObjectProperty(isolate, obj, key), Object);
-}
-
-
-Handle<String> LookupSingleCharacterStringFromCode(Isolate* isolate,
- uint32_t index) {
- CALL_HEAP_FUNCTION(
- isolate,
- isolate->heap()->LookupSingleCharacterStringFromCode(index),
- String);
-}
-
-
-// Wrappers for scripts are kept alive and cached in weak global
-// handles referred from foreign objects held by the scripts as long as
-// they are used. When they are not used anymore, the garbage
-// collector will call the weak callback on the global handle
-// associated with the wrapper and get rid of both the wrapper and the
-// handle.
-static void ClearWrapperCache(
- const v8::WeakCallbackData<v8::Value, void>& data) {
- Object** location = reinterpret_cast<Object**>(data.GetParameter());
- JSValue* wrapper = JSValue::cast(*location);
- Foreign* foreign = Script::cast(wrapper->value())->wrapper();
- ASSERT_EQ(foreign->foreign_address(), reinterpret_cast<Address>(location));
- foreign->set_foreign_address(0);
- GlobalHandles::Destroy(location);
- Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate());
- isolate->counters()->script_wrappers()->Decrement();
-}
-
-
-Handle<JSValue> GetScriptWrapper(Handle<Script> script) {
- if (script->wrapper()->foreign_address() != NULL) {
- // Return a handle for the existing script wrapper from the cache.
- return Handle<JSValue>(
- *reinterpret_cast<JSValue**>(script->wrapper()->foreign_address()));
- }
- Isolate* isolate = script->GetIsolate();
- // Construct a new script wrapper.
- isolate->counters()->script_wrappers()->Increment();
- Handle<JSFunction> constructor = isolate->script_function();
- Handle<JSValue> result =
- Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
-
- // The allocation might have triggered a GC, which could have called this
- // function recursively, and a wrapper has already been created and cached.
- // In that case, simply return a handle for the cached wrapper.
- if (script->wrapper()->foreign_address() != NULL) {
- return Handle<JSValue>(
- *reinterpret_cast<JSValue**>(script->wrapper()->foreign_address()));
- }
-
- result->set_value(*script);
-
- // Create a new weak global handle and use it to cache the wrapper
- // for future use. The cache will automatically be cleared by the
- // garbage collector when it is not used anymore.
- Handle<Object> handle = isolate->global_handles()->Create(*result);
- GlobalHandles::MakeWeak(handle.location(),
- reinterpret_cast<void*>(handle.location()),
- &ClearWrapperCache);
- script->wrapper()->set_foreign_address(
- reinterpret_cast<Address>(handle.location()));
- return result;
-}
-
-
-// Init line_ends array with code positions of line ends inside script
-// source.
-void InitScriptLineEnds(Handle<Script> script) {
- if (!script->line_ends()->IsUndefined()) return;
-
- Isolate* isolate = script->GetIsolate();
-
- if (!script->source()->IsString()) {
- ASSERT(script->source()->IsUndefined());
- Handle<FixedArray> empty = isolate->factory()->NewFixedArray(0);
- script->set_line_ends(*empty);
- ASSERT(script->line_ends()->IsFixedArray());
- return;
- }
-
- Handle<String> src(String::cast(script->source()), isolate);
-
- Handle<FixedArray> array = CalculateLineEnds(src, true);
-
- if (*array != isolate->heap()->empty_fixed_array()) {
- array->set_map(isolate->heap()->fixed_cow_array_map());
- }
-
- script->set_line_ends(*array);
- ASSERT(script->line_ends()->IsFixedArray());
-}
-
-
-template <typename SourceChar>
-static void CalculateLineEnds(Isolate* isolate,
- List<int>* line_ends,
- Vector<const SourceChar> src,
- bool with_last_line) {
- const int src_len = src.length();
- StringSearch<uint8_t, SourceChar> search(isolate, STATIC_ASCII_VECTOR("\n"));
-
- // Find and record line ends.
- int position = 0;
- while (position != -1 && position < src_len) {
- position = search.Search(src, position);
- if (position != -1) {
- line_ends->Add(position);
- position++;
- } else if (with_last_line) {
- // Even if the last line misses a line end, it is counted.
- line_ends->Add(src_len);
- return;
- }
- }
-}
-
-
-Handle<FixedArray> CalculateLineEnds(Handle<String> src,
- bool with_last_line) {
- src = FlattenGetString(src);
- // Rough estimate of line count based on a roughly estimated average
- // length of (unpacked) code.
- int line_count_estimate = src->length() >> 4;
- List<int> line_ends(line_count_estimate);
- Isolate* isolate = src->GetIsolate();
- {
- DisallowHeapAllocation no_allocation; // ensure vectors stay valid.
- // Dispatch on type of strings.
- String::FlatContent content = src->GetFlatContent();
- ASSERT(content.IsFlat());
- if (content.IsAscii()) {
- CalculateLineEnds(isolate,
- &line_ends,
- content.ToOneByteVector(),
- with_last_line);
- } else {
- CalculateLineEnds(isolate,
- &line_ends,
- content.ToUC16Vector(),
- with_last_line);
- }
- }
- int line_count = line_ends.length();
- Handle<FixedArray> array = isolate->factory()->NewFixedArray(line_count);
- for (int i = 0; i < line_count; i++) {
- array->set(i, Smi::FromInt(line_ends[i]));
- }
- return array;
-}
-
-
-// Convert code position into line number.
-int GetScriptLineNumber(Handle<Script> script, int code_pos) {
- InitScriptLineEnds(script);
- DisallowHeapAllocation no_allocation;
- FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
- const int line_ends_len = line_ends_array->length();
-
- if (!line_ends_len) return -1;
-
- if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos) {
- return script->line_offset()->value();
- }
-
- int left = 0;
- int right = line_ends_len;
- while (int half = (right - left) / 2) {
- if ((Smi::cast(line_ends_array->get(left + half)))->value() > code_pos) {
- right -= half;
- } else {
- left += half;
- }
- }
- return right + script->line_offset()->value();
-}
-
-
-// Convert code position into column number.
-int GetScriptColumnNumber(Handle<Script> script, int code_pos) {
- int line_number = GetScriptLineNumber(script, code_pos);
- if (line_number == -1) return -1;
-
- DisallowHeapAllocation no_allocation;
- FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
- line_number = line_number - script->line_offset()->value();
- if (line_number == 0) return code_pos + script->column_offset()->value();
- int prev_line_end_pos =
- Smi::cast(line_ends_array->get(line_number - 1))->value();
- return code_pos - (prev_line_end_pos + 1);
-}
-
-
-int GetScriptLineNumberSafe(Handle<Script> script, int code_pos) {
- DisallowHeapAllocation no_allocation;
- if (!script->line_ends()->IsUndefined()) {
- return GetScriptLineNumber(script, code_pos);
- }
- // Slow mode: we do not have line_ends. We have to iterate through source.
- if (!script->source()->IsString()) {
- return -1;
- }
- String* source = String::cast(script->source());
- int line = 0;
- int len = source->length();
- for (int pos = 0; pos < len; pos++) {
- if (pos == code_pos) {
- break;
- }
- if (source->Get(pos) == '\n') {
- line++;
- }
- }
- return line;
-}
-
-
-// Compute the property keys from the interceptor.
-// TODO(rossberg): support symbols in API, and filter here if needed.
-v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSReceiver> receiver,
- Handle<JSObject> object) {
- Isolate* isolate = receiver->GetIsolate();
- Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
- PropertyCallbackArguments
- args(isolate, interceptor->data(), *receiver, *object);
- v8::Handle<v8::Array> result;
- if (!interceptor->enumerator()->IsUndefined()) {
- v8::NamedPropertyEnumeratorCallback enum_fun =
- v8::ToCData<v8::NamedPropertyEnumeratorCallback>(
- interceptor->enumerator());
- LOG(isolate, ApiObjectAccess("interceptor-named-enum", *object));
- result = args.Call(enum_fun);
- }
-#if ENABLE_EXTRA_CHECKS
- CHECK(result.IsEmpty() || v8::Utils::OpenHandle(*result)->IsJSObject());
-#endif
- return v8::Local<v8::Array>::New(reinterpret_cast<v8::Isolate*>(isolate),
- result);
-}
-
-
-// Compute the element keys from the interceptor.
-v8::Handle<v8::Array> GetKeysForIndexedInterceptor(Handle<JSReceiver> receiver,
- Handle<JSObject> object) {
- Isolate* isolate = receiver->GetIsolate();
- Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
- PropertyCallbackArguments
- args(isolate, interceptor->data(), *receiver, *object);
- v8::Handle<v8::Array> result;
- if (!interceptor->enumerator()->IsUndefined()) {
- v8::IndexedPropertyEnumeratorCallback enum_fun =
- v8::ToCData<v8::IndexedPropertyEnumeratorCallback>(
- interceptor->enumerator());
- LOG(isolate, ApiObjectAccess("interceptor-indexed-enum", *object));
- result = args.Call(enum_fun);
-#if ENABLE_EXTRA_CHECKS
- CHECK(result.IsEmpty() || v8::Utils::OpenHandle(*result)->IsJSObject());
-#endif
- }
- return v8::Local<v8::Array>::New(reinterpret_cast<v8::Isolate*>(isolate),
- result);
-}
-
-
-Handle<Object> GetScriptNameOrSourceURL(Handle<Script> script) {
- Isolate* isolate = script->GetIsolate();
- Handle<String> name_or_source_url_key =
- isolate->factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("nameOrSourceURL"));
- Handle<JSValue> script_wrapper = GetScriptWrapper(script);
- Handle<Object> property = GetProperty(isolate,
- script_wrapper,
- name_or_source_url_key);
- ASSERT(property->IsJSFunction());
- Handle<JSFunction> method = Handle<JSFunction>::cast(property);
- bool caught_exception;
- Handle<Object> result = Execution::TryCall(method, script_wrapper, 0,
- NULL, &caught_exception);
- if (caught_exception) {
- result = isolate->factory()->undefined_value();
- }
- return result;
-}
-
-
-static bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
- int len = array->length();
- for (int i = 0; i < len; i++) {
- Object* e = array->get(i);
- if (!(e->IsString() || e->IsNumber())) return false;
- }
- return true;
-}
-
-
-Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSReceiver> object,
- KeyCollectionType type,
- bool* threw) {
- USE(ContainsOnlyValidKeys);
- Isolate* isolate = object->GetIsolate();
- Handle<FixedArray> content = isolate->factory()->empty_fixed_array();
- Handle<JSObject> arguments_boilerplate = Handle<JSObject>(
- isolate->context()->native_context()->sloppy_arguments_boilerplate(),
- isolate);
- Handle<JSFunction> arguments_function = Handle<JSFunction>(
- JSFunction::cast(arguments_boilerplate->map()->constructor()),
- isolate);
-
- // Only collect keys if access is permitted.
- for (Handle<Object> p = object;
- *p != isolate->heap()->null_value();
- p = Handle<Object>(p->GetPrototype(isolate), isolate)) {
- if (p->IsJSProxy()) {
- Handle<JSProxy> proxy(JSProxy::cast(*p), isolate);
- Handle<Object> args[] = { proxy };
- Handle<Object> names = Execution::Call(isolate,
- isolate->proxy_enumerate(),
- object,
- ARRAY_SIZE(args),
- args,
- threw);
- if (*threw) return content;
- content = AddKeysFromJSArray(content, Handle<JSArray>::cast(names));
- break;
- }
-
- Handle<JSObject> current(JSObject::cast(*p), isolate);
-
- // Check access rights if required.
- if (current->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(current,
- isolate->factory()->undefined_value(),
- v8::ACCESS_KEYS)) {
- isolate->ReportFailedAccessCheckWrapper(current, v8::ACCESS_KEYS);
- if (isolate->has_scheduled_exception()) {
- isolate->PromoteScheduledException();
- *threw = true;
- }
- break;
- }
-
- // Compute the element keys.
- Handle<FixedArray> element_keys =
- isolate->factory()->NewFixedArray(current->NumberOfEnumElements());
- current->GetEnumElementKeys(*element_keys);
- content = UnionOfKeys(content, element_keys);
- ASSERT(ContainsOnlyValidKeys(content));
-
- // Add the element keys from the interceptor.
- if (current->HasIndexedInterceptor()) {
- v8::Handle<v8::Array> result =
- GetKeysForIndexedInterceptor(object, current);
- if (!result.IsEmpty())
- content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
- ASSERT(ContainsOnlyValidKeys(content));
- }
-
- // We can cache the computed property keys if access checks are
- // not needed and no interceptors are involved.
- //
- // We do not use the cache if the object has elements and
- // therefore it does not make sense to cache the property names
- // for arguments objects. Arguments objects will always have
- // elements.
- // Wrapped strings have elements, but don't have an elements
- // array or dictionary. So the fast inline test for whether to
- // use the cache says yes, so we should not create a cache.
- bool cache_enum_keys =
- ((current->map()->constructor() != *arguments_function) &&
- !current->IsJSValue() &&
- !current->IsAccessCheckNeeded() &&
- !current->HasNamedInterceptor() &&
- !current->HasIndexedInterceptor());
- // Compute the property keys and cache them if possible.
- content =
- UnionOfKeys(content, GetEnumPropertyKeys(current, cache_enum_keys));
- ASSERT(ContainsOnlyValidKeys(content));
-
- // Add the property keys from the interceptor.
- if (current->HasNamedInterceptor()) {
- v8::Handle<v8::Array> result =
- GetKeysForNamedInterceptor(object, current);
- if (!result.IsEmpty())
- content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
- ASSERT(ContainsOnlyValidKeys(content));
- }
-
- // If we only want local properties we bail out after the first
- // iteration.
- if (type == LOCAL_ONLY)
- break;
- }
- return content;
-}
-
-
-Handle<JSArray> GetKeysFor(Handle<JSReceiver> object, bool* threw) {
- Isolate* isolate = object->GetIsolate();
- isolate->counters()->for_in()->Increment();
- Handle<FixedArray> elements =
- GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, threw);
- return isolate->factory()->NewJSArrayWithElements(elements);
-}
-
-
-Handle<FixedArray> ReduceFixedArrayTo(Handle<FixedArray> array, int length) {
- ASSERT(array->length() >= length);
- if (array->length() == length) return array;
-
- Handle<FixedArray> new_array =
- array->GetIsolate()->factory()->NewFixedArray(length);
- for (int i = 0; i < length; ++i) new_array->set(i, array->get(i));
- return new_array;
-}
-
-
-Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object,
- bool cache_result) {
- Isolate* isolate = object->GetIsolate();
- if (object->HasFastProperties()) {
- if (object->map()->instance_descriptors()->HasEnumCache()) {
- int own_property_count = object->map()->EnumLength();
- // If we have an enum cache, but the enum length of the given map is set
- // to kInvalidEnumCache, this means that the map itself has never used the
- // present enum cache. The first step to using the cache is to set the
- // enum length of the map by counting the number of own descriptors that
- // are not DONT_ENUM or SYMBOLIC.
- if (own_property_count == kInvalidEnumCacheSentinel) {
- own_property_count = object->map()->NumberOfDescribedProperties(
- OWN_DESCRIPTORS, DONT_SHOW);
-
- if (cache_result) object->map()->SetEnumLength(own_property_count);
- }
-
- DescriptorArray* desc = object->map()->instance_descriptors();
- Handle<FixedArray> keys(desc->GetEnumCache(), isolate);
-
- // In case the number of properties required in the enum are actually
- // present, we can reuse the enum cache. Otherwise, this means that the
- // enum cache was generated for a previous (smaller) version of the
- // Descriptor Array. In that case we regenerate the enum cache.
- if (own_property_count <= keys->length()) {
- isolate->counters()->enum_cache_hits()->Increment();
- return ReduceFixedArrayTo(keys, own_property_count);
- }
- }
-
- Handle<Map> map(object->map());
-
- if (map->instance_descriptors()->IsEmpty()) {
- isolate->counters()->enum_cache_hits()->Increment();
- if (cache_result) map->SetEnumLength(0);
- return isolate->factory()->empty_fixed_array();
- }
-
- isolate->counters()->enum_cache_misses()->Increment();
- int num_enum = map->NumberOfDescribedProperties(ALL_DESCRIPTORS, DONT_SHOW);
-
- Handle<FixedArray> storage = isolate->factory()->NewFixedArray(num_enum);
- Handle<FixedArray> indices = isolate->factory()->NewFixedArray(num_enum);
-
- Handle<DescriptorArray> descs =
- Handle<DescriptorArray>(object->map()->instance_descriptors(), isolate);
-
- int real_size = map->NumberOfOwnDescriptors();
- int enum_size = 0;
- int index = 0;
-
- for (int i = 0; i < descs->number_of_descriptors(); i++) {
- PropertyDetails details = descs->GetDetails(i);
- Object* key = descs->GetKey(i);
- if (!(details.IsDontEnum() || key->IsSymbol())) {
- if (i < real_size) ++enum_size;
- storage->set(index, key);
- if (!indices.is_null()) {
- if (details.type() != FIELD) {
- indices = Handle<FixedArray>();
- } else {
- int field_index = descs->GetFieldIndex(i);
- if (field_index >= map->inobject_properties()) {
- field_index = -(field_index - map->inobject_properties() + 1);
- }
- indices->set(index, Smi::FromInt(field_index));
- }
- }
- index++;
- }
- }
- ASSERT(index == storage->length());
-
- Handle<FixedArray> bridge_storage =
- isolate->factory()->NewFixedArray(
- DescriptorArray::kEnumCacheBridgeLength);
- DescriptorArray* desc = object->map()->instance_descriptors();
- desc->SetEnumCache(*bridge_storage,
- *storage,
- indices.is_null() ? Object::cast(Smi::FromInt(0))
- : Object::cast(*indices));
- if (cache_result) {
- object->map()->SetEnumLength(enum_size);
- }
-
- return ReduceFixedArrayTo(storage, enum_size);
- } else {
- Handle<NameDictionary> dictionary(object->property_dictionary());
- int length = dictionary->NumberOfEnumElements();
- if (length == 0) {
- return Handle<FixedArray>(isolate->heap()->empty_fixed_array());
- }
- Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length);
- dictionary->CopyEnumKeysTo(*storage);
- return storage;
- }
-}
-
-
DeferredHandleScope::DeferredHandleScope(Isolate* isolate)
: impl_(isolate->handle_scope_implementer()) {
impl_->BeginDeferredScope();
@@ -761,16 +127,4 @@ DeferredHandles* DeferredHandleScope::Detach() {
return deferred;
}
-
-void AddWeakObjectToCodeDependency(Heap* heap,
- Handle<Object> object,
- Handle<Code> code) {
- heap->EnsureWeakObjectToCodeTable();
- Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(*object));
- dep = DependentCode::Insert(dep, DependentCode::kWeaklyEmbeddedGroup, code);
- CALL_HEAP_FUNCTION_VOID(heap->isolate(),
- heap->AddWeakObjectToCodeDependency(*object, *dep));
-}
-
-
} } // namespace v8::internal
diff --git a/deps/v8/src/handles.h b/deps/v8/src/handles.h
index 8538658047..5dc4a5ddda 100644
--- a/deps/v8/src/handles.h
+++ b/deps/v8/src/handles.h
@@ -1,39 +1,78 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HANDLES_H_
#define V8_HANDLES_H_
-#include "allocation.h"
#include "objects.h"
namespace v8 {
namespace internal {
+// A Handle can be converted into a MaybeHandle. Converting a MaybeHandle
+// into a Handle requires checking that it does not point to NULL. This
+// ensures NULL checks before use.
+// Do not use MaybeHandle as argument type.
+
+template<typename T>
+class MaybeHandle {
+ public:
+ INLINE(MaybeHandle()) : location_(NULL) { }
+
+ // Constructor for handling automatic up casting from Handle.
+ // Ex. Handle<JSArray> can be passed when MaybeHandle<Object> is expected.
+ template <class S> MaybeHandle(Handle<S> handle) {
+#ifdef DEBUG
+ T* a = NULL;
+ S* b = NULL;
+ a = b; // Fake assignment to enforce type checks.
+ USE(a);
+#endif
+ this->location_ = reinterpret_cast<T**>(handle.location());
+ }
+
+ // Constructor for handling automatic up casting.
+ // Ex. MaybeHandle<JSArray> can be passed when Handle<Object> is expected.
+ template <class S> MaybeHandle(MaybeHandle<S> maybe_handle) {
+#ifdef DEBUG
+ T* a = NULL;
+ S* b = NULL;
+ a = b; // Fake assignment to enforce type checks.
+ USE(a);
+#endif
+ location_ = reinterpret_cast<T**>(maybe_handle.location_);
+ }
+
+ INLINE(void Assert()) { ASSERT(location_ != NULL); }
+ INLINE(void Check()) { CHECK(location_ != NULL); }
+
+ INLINE(Handle<T> ToHandleChecked()) {
+ Check();
+ return Handle<T>(location_);
+ }
+
+ // Convert to a Handle with a type that can be upcasted to.
+ template <class S> INLINE(bool ToHandle(Handle<S>* out)) {
+ if (location_ == NULL) {
+ *out = Handle<T>::null();
+ return false;
+ } else {
+ *out = Handle<T>(location_);
+ return true;
+ }
+ }
+
+ bool is_null() const { return location_ == NULL; }
+
+ protected:
+ T** location_;
+
+ // MaybeHandles of different classes are allowed to access each
+ // other's location_.
+ template<class S> friend class MaybeHandle;
+};
+
// ----------------------------------------------------------------------------
// A Handle provides a reference to an object that survives relocation by
// the garbage collector.
@@ -47,7 +86,9 @@ class Handle {
INLINE(explicit Handle(T* obj));
INLINE(Handle(T* obj, Isolate* isolate));
- INLINE(Handle()) : location_(NULL) {}
+ // TODO(yangguo): Values that contain empty handles should be declared as
+ // MaybeHandle to force validation before being used as handles.
+ INLINE(Handle()) : location_(NULL) { }
// Constructor for handling automatic up casting.
// Ex. Handle<JSFunction> can be passed when Handle<Object> is expected.
@@ -77,6 +118,8 @@ class Handle {
return Handle<T>(reinterpret_cast<T**>(that.location_));
}
+ // TODO(yangguo): Values that contain empty handles should be declared as
+ // MaybeHandle to force validation before being used as handles.
static Handle<T> null() { return Handle<T>(); }
bool is_null() const { return location_ == NULL; }
@@ -112,6 +155,13 @@ inline Handle<T> handle(T* t) {
}
+// Key comparison function for Map handles.
+inline bool operator<(const Handle<Map>& lhs, const Handle<Map>& rhs) {
+ // This is safe because maps don't move.
+ return *lhs < *rhs;
+}
+
+
class DeferredHandles;
class HandleScopeImplementer;
@@ -214,91 +264,6 @@ class DeferredHandleScope {
};
-// ----------------------------------------------------------------------------
-// Handle operations.
-// They might invoke garbage collection. The result is an handle to
-// an object of expected type, or the handle is an error if running out
-// of space or encountering an internal error.
-
-// Flattens a string.
-void FlattenString(Handle<String> str);
-
-// Flattens a string and returns the underlying external or sequential
-// string.
-Handle<String> FlattenGetString(Handle<String> str);
-
-Handle<Object> ForceSetProperty(Handle<JSObject> object,
- Handle<Object> key,
- Handle<Object> value,
- PropertyAttributes attributes);
-
-Handle<Object> DeleteProperty(Handle<JSObject> object, Handle<Object> key);
-
-Handle<Object> ForceDeleteProperty(Handle<JSObject> object, Handle<Object> key);
-
-Handle<Object> HasProperty(Handle<JSReceiver> obj, Handle<Object> key);
-
-Handle<Object> GetProperty(Handle<JSReceiver> obj, const char* name);
-
-Handle<Object> GetProperty(Isolate* isolate,
- Handle<Object> obj,
- Handle<Object> key);
-
-Handle<String> LookupSingleCharacterStringFromCode(Isolate* isolate,
- uint32_t index);
-
-Handle<FixedArray> AddKeysFromJSArray(Handle<FixedArray>,
- Handle<JSArray> array);
-
-// Get the JS object corresponding to the given script; create it
-// if none exists.
-Handle<JSValue> GetScriptWrapper(Handle<Script> script);
-
-// Script line number computations. Note that the line number is zero-based.
-void InitScriptLineEnds(Handle<Script> script);
-// For string calculates an array of line end positions. If the string
-// does not end with a new line character, this character may optionally be
-// imagined.
-Handle<FixedArray> CalculateLineEnds(Handle<String> string,
- bool with_imaginary_last_new_line);
-int GetScriptLineNumber(Handle<Script> script, int code_position);
-// The safe version does not make heap allocations but may work much slower.
-int GetScriptLineNumberSafe(Handle<Script> script, int code_position);
-int GetScriptColumnNumber(Handle<Script> script, int code_position);
-Handle<Object> GetScriptNameOrSourceURL(Handle<Script> script);
-
-// Computes the enumerable keys from interceptors. Used for debug mirrors and
-// by GetKeysInFixedArrayFor below.
-v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSReceiver> receiver,
- Handle<JSObject> object);
-v8::Handle<v8::Array> GetKeysForIndexedInterceptor(Handle<JSReceiver> receiver,
- Handle<JSObject> object);
-
-enum KeyCollectionType { LOCAL_ONLY, INCLUDE_PROTOS };
-
-// Computes the enumerable keys for a JSObject. Used for implementing
-// "for (n in object) { }".
-Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSReceiver> object,
- KeyCollectionType type,
- bool* threw);
-Handle<JSArray> GetKeysFor(Handle<JSReceiver> object, bool* threw);
-Handle<FixedArray> ReduceFixedArrayTo(Handle<FixedArray> array, int length);
-Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object,
- bool cache_result);
-
-// Computes the union of keys and return the result.
-// Used for implementing "for (n in object) { }"
-Handle<FixedArray> UnionOfKeys(Handle<FixedArray> first,
- Handle<FixedArray> second);
-
-Handle<JSGlobalProxy> ReinitializeJSGlobalProxy(
- Handle<JSFunction> constructor,
- Handle<JSGlobalProxy> global);
-
-void AddWeakObjectToCodeDependency(Heap* heap,
- Handle<Object> object,
- Handle<Code> code);
-
// Seal off the current HandleScope so that new handles can only be created
// if a new HandleScope is entered.
class SealHandleScope BASE_EMBEDDED {
diff --git a/deps/v8/src/harmony-array.js b/deps/v8/src/harmony-array.js
index d37d875385..dbcb292a08 100644
--- a/deps/v8/src/harmony-array.js
+++ b/deps/v8/src/harmony-array.js
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
'use strict';
@@ -103,6 +80,49 @@ function ArrayFindIndex(predicate /* thisArg */) { // length == 1
}
+// ES6, draft 04-05-14, section 22.1.3.6
+function ArrayFill(value /* [, start [, end ] ] */) { // length == 1
+ CHECK_OBJECT_COERCIBLE(this, "Array.prototype.fill");
+
+ var array = ToObject(this);
+ var length = TO_UINT32(array.length);
+
+ var i = 0;
+ var end = length;
+
+ if (%_ArgumentsLength() > 1) {
+ i = %_Arguments(1);
+ i = IS_UNDEFINED(i) ? 0 : TO_INTEGER(i);
+ if (%_ArgumentsLength() > 2) {
+ end = %_Arguments(2);
+ end = IS_UNDEFINED(end) ? length : TO_INTEGER(end);
+ }
+ }
+
+ if (i < 0) {
+ i += length;
+ if (i < 0) i = 0;
+ } else {
+ if (i > length) i = length;
+ }
+
+ if (end < 0) {
+ end += length;
+ if (end < 0) end = 0;
+ } else {
+ if (end > length) end = length;
+ }
+
+ if ((end - i) > 0 && ObjectIsFrozen(array)) {
+ throw MakeTypeError("array_functions_on_frozen",
+ ["Array.prototype.fill"]);
+ }
+
+ for (; i < end; i++)
+ array[i] = value;
+ return array;
+}
+
// -------------------------------------------------------------------
function HarmonyArrayExtendArrayPrototype() {
@@ -111,7 +131,8 @@ function HarmonyArrayExtendArrayPrototype() {
// Set up the non-enumerable functions on the Array prototype object.
InstallFunctions($Array.prototype, DONT_ENUM, $Array(
"find", ArrayFind,
- "findIndex", ArrayFindIndex
+ "findIndex", ArrayFindIndex,
+ "fill", ArrayFill
));
}
diff --git a/deps/v8/src/harmony-math.js b/deps/v8/src/harmony-math.js
index 298fa58cb2..505e9a163f 100644
--- a/deps/v8/src/harmony-math.js
+++ b/deps/v8/src/harmony-math.js
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
'use strict';
@@ -156,7 +133,7 @@ function MathHypot(x, y) { // Function length is 2.
// ES6 draft 09-27-13, section 20.2.2.16.
function MathFround(x) {
- return %Math_fround(TO_NUMBER_INLINE(x));
+ return %MathFround(TO_NUMBER_INLINE(x));
}
diff --git a/deps/v8/src/harmony-string.js b/deps/v8/src/harmony-string.js
index cc3c5cf93c..4cd8e6687e 100644
--- a/deps/v8/src/harmony-string.js
+++ b/deps/v8/src/harmony-string.js
@@ -1,29 +1,6 @@
// Copyright 2014 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
'use strict';
@@ -53,7 +30,7 @@ function StringRepeat(count) {
}
-// ES6 draft 01-20-14, section 21.1.3.18
+// ES6 draft 04-05-14, section 21.1.3.18
function StringStartsWith(searchString /* position */) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "String.prototype.startsWith");
@@ -82,7 +59,7 @@ function StringStartsWith(searchString /* position */) { // length == 1
}
-// ES6 draft 01-20-14, section 21.1.3.7
+// ES6 draft 04-05-14, section 21.1.3.7
function StringEndsWith(searchString /* position */) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "String.prototype.endsWith");
@@ -114,11 +91,17 @@ function StringEndsWith(searchString /* position */) { // length == 1
}
-// ES6 draft 01-20-14, section 21.1.3.6
+// ES6 draft 04-05-14, section 21.1.3.6
function StringContains(searchString /* position */) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "String.prototype.contains");
var s = TO_STRING_INLINE(this);
+
+ if (IS_REGEXP(searchString)) {
+ throw MakeTypeError("first_argument_not_regexp",
+ ["String.prototype.contains"]);
+ }
+
var ss = TO_STRING_INLINE(searchString);
var pos = 0;
if (%_ArgumentsLength() > 1) {
diff --git a/deps/v8/src/hashmap.h b/deps/v8/src/hashmap.h
index 11f6ace7d8..4a363b7ce0 100644
--- a/deps/v8/src/hashmap.h
+++ b/deps/v8/src/hashmap.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HASHMAP_H_
#define V8_HASHMAP_H_
@@ -98,6 +75,11 @@ class TemplateHashMapImpl {
Entry* Start() const;
Entry* Next(Entry* p) const;
+ // Some match functions defined for convenience.
+ static bool PointersMatch(void* key1, void* key2) {
+ return key1 == key2;
+ }
+
private:
MatchFun match_;
Entry* map_;
diff --git a/deps/v8/src/heap-inl.h b/deps/v8/src/heap-inl.h
index 063cf30ff3..3cddcb91dc 100644
--- a/deps/v8/src/heap-inl.h
+++ b/deps/v8/src/heap-inl.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HEAP_INL_H_
#define V8_HEAP_INL_H_
@@ -36,7 +13,6 @@
#include "list-inl.h"
#include "objects.h"
#include "platform.h"
-#include "v8-counters.h"
#include "store-buffer.h"
#include "store-buffer-inl.h"
@@ -85,22 +61,6 @@ void PromotionQueue::ActivateGuardIfOnTheSamePage() {
}
-MaybeObject* Heap::AllocateStringFromUtf8(Vector<const char> str,
- PretenureFlag pretenure) {
- // Check for ASCII first since this is the common case.
- const char* start = str.start();
- int length = str.length();
- int non_ascii_start = String::NonAsciiStart(start, length);
- if (non_ascii_start >= length) {
- // If the string is ASCII, we do not need to convert the characters
- // since UTF8 is backwards compatible with ASCII.
- return AllocateStringFromOneByte(str, pretenure);
- }
- // Non-ASCII and we need to decode.
- return AllocateStringFromUtf8Slow(str, non_ascii_start, pretenure);
-}
-
-
template<>
bool inline Heap::IsOneByte(Vector<const char> str, int chars) {
// TODO(dcarney): incorporate Latin-1 check when Latin-1 is supported?
@@ -115,7 +75,7 @@ bool inline Heap::IsOneByte(String* str, int chars) {
}
-MaybeObject* Heap::AllocateInternalizedStringFromUtf8(
+AllocationResult Heap::AllocateInternalizedStringFromUtf8(
Vector<const char> str, int chars, uint32_t hash_field) {
if (IsOneByte(str, chars)) {
return AllocateOneByteInternalizedString(
@@ -126,7 +86,7 @@ MaybeObject* Heap::AllocateInternalizedStringFromUtf8(
template<typename T>
-MaybeObject* Heap::AllocateInternalizedStringImpl(
+AllocationResult Heap::AllocateInternalizedStringImpl(
T t, int chars, uint32_t hash_field) {
if (IsOneByte(t, chars)) {
return AllocateInternalizedStringImpl<true>(t, chars, hash_field);
@@ -135,8 +95,9 @@ MaybeObject* Heap::AllocateInternalizedStringImpl(
}
-MaybeObject* Heap::AllocateOneByteInternalizedString(Vector<const uint8_t> str,
- uint32_t hash_field) {
+AllocationResult Heap::AllocateOneByteInternalizedString(
+ Vector<const uint8_t> str,
+ uint32_t hash_field) {
if (str.length() > String::kMaxLength) {
return isolate()->ThrowInvalidStringLength();
}
@@ -146,13 +107,13 @@ MaybeObject* Heap::AllocateOneByteInternalizedString(Vector<const uint8_t> str,
AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, TENURED);
// Allocate string.
- Object* result;
- { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ HeapObject* result;
+ { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
+ if (!allocation.To(&result)) return allocation;
}
// String maps are all immortal immovable objects.
- reinterpret_cast<HeapObject*>(result)->set_map_no_write_barrier(map);
+ result->set_map_no_write_barrier(map);
// Set length and hash fields of the allocated string.
String* answer = String::cast(result);
answer->set_length(str.length());
@@ -168,8 +129,8 @@ MaybeObject* Heap::AllocateOneByteInternalizedString(Vector<const uint8_t> str,
}
-MaybeObject* Heap::AllocateTwoByteInternalizedString(Vector<const uc16> str,
- uint32_t hash_field) {
+AllocationResult Heap::AllocateTwoByteInternalizedString(Vector<const uc16> str,
+ uint32_t hash_field) {
if (str.length() > String::kMaxLength) {
return isolate()->ThrowInvalidStringLength();
}
@@ -179,12 +140,12 @@ MaybeObject* Heap::AllocateTwoByteInternalizedString(Vector<const uc16> str,
AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, TENURED);
// Allocate string.
- Object* result;
- { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ HeapObject* result;
+ { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
+ if (!allocation.To(&result)) return allocation;
}
- reinterpret_cast<HeapObject*>(result)->set_map(map);
+ result->set_map(map);
// Set length and hash fields of the allocated string.
String* answer = String::cast(result);
answer->set_length(str.length());
@@ -199,24 +160,27 @@ MaybeObject* Heap::AllocateTwoByteInternalizedString(Vector<const uc16> str,
return answer;
}
-MaybeObject* Heap::CopyFixedArray(FixedArray* src) {
+AllocationResult Heap::CopyFixedArray(FixedArray* src) {
+ if (src->length() == 0) return src;
return CopyFixedArrayWithMap(src, src->map());
}
-MaybeObject* Heap::CopyFixedDoubleArray(FixedDoubleArray* src) {
+AllocationResult Heap::CopyFixedDoubleArray(FixedDoubleArray* src) {
+ if (src->length() == 0) return src;
return CopyFixedDoubleArrayWithMap(src, src->map());
}
-MaybeObject* Heap::CopyConstantPoolArray(ConstantPoolArray* src) {
+AllocationResult Heap::CopyConstantPoolArray(ConstantPoolArray* src) {
+ if (src->length() == 0) return src;
return CopyConstantPoolArrayWithMap(src, src->map());
}
-MaybeObject* Heap::AllocateRaw(int size_in_bytes,
- AllocationSpace space,
- AllocationSpace retry_space) {
+AllocationResult Heap::AllocateRaw(int size_in_bytes,
+ AllocationSpace space,
+ AllocationSpace retry_space) {
ASSERT(AllowHandleAllocation::IsAllowed());
ASSERT(AllowHeapAllocation::IsAllowed());
ASSERT(gc_state_ == NOT_IN_GC);
@@ -225,66 +189,49 @@ MaybeObject* Heap::AllocateRaw(int size_in_bytes,
if (FLAG_gc_interval >= 0 &&
AllowAllocationFailure::IsAllowed(isolate_) &&
Heap::allocation_timeout_-- <= 0) {
- return Failure::RetryAfterGC(space);
+ return AllocationResult::Retry(space);
}
isolate_->counters()->objs_since_last_full()->Increment();
isolate_->counters()->objs_since_last_young()->Increment();
#endif
HeapObject* object;
- MaybeObject* result;
+ AllocationResult allocation;
if (NEW_SPACE == space) {
- result = new_space_.AllocateRaw(size_in_bytes);
- if (always_allocate() && result->IsFailure() && retry_space != NEW_SPACE) {
+ allocation = new_space_.AllocateRaw(size_in_bytes);
+ if (always_allocate() &&
+ allocation.IsRetry() &&
+ retry_space != NEW_SPACE) {
space = retry_space;
} else {
- if (profiler->is_tracking_allocations() && result->To(&object)) {
+ if (profiler->is_tracking_allocations() && allocation.To(&object)) {
profiler->AllocationEvent(object->address(), size_in_bytes);
}
- return result;
+ return allocation;
}
}
if (OLD_POINTER_SPACE == space) {
- result = old_pointer_space_->AllocateRaw(size_in_bytes);
+ allocation = old_pointer_space_->AllocateRaw(size_in_bytes);
} else if (OLD_DATA_SPACE == space) {
- result = old_data_space_->AllocateRaw(size_in_bytes);
+ allocation = old_data_space_->AllocateRaw(size_in_bytes);
} else if (CODE_SPACE == space) {
- result = code_space_->AllocateRaw(size_in_bytes);
+ allocation = code_space_->AllocateRaw(size_in_bytes);
} else if (LO_SPACE == space) {
- result = lo_space_->AllocateRaw(size_in_bytes, NOT_EXECUTABLE);
+ allocation = lo_space_->AllocateRaw(size_in_bytes, NOT_EXECUTABLE);
} else if (CELL_SPACE == space) {
- result = cell_space_->AllocateRaw(size_in_bytes);
+ allocation = cell_space_->AllocateRaw(size_in_bytes);
} else if (PROPERTY_CELL_SPACE == space) {
- result = property_cell_space_->AllocateRaw(size_in_bytes);
+ allocation = property_cell_space_->AllocateRaw(size_in_bytes);
} else {
ASSERT(MAP_SPACE == space);
- result = map_space_->AllocateRaw(size_in_bytes);
+ allocation = map_space_->AllocateRaw(size_in_bytes);
}
- if (result->IsFailure()) old_gen_exhausted_ = true;
- if (profiler->is_tracking_allocations() && result->To(&object)) {
+ if (allocation.IsRetry()) old_gen_exhausted_ = true;
+ if (profiler->is_tracking_allocations() && allocation.To(&object)) {
profiler->AllocationEvent(object->address(), size_in_bytes);
}
- return result;
-}
-
-
-MaybeObject* Heap::NumberFromInt32(
- int32_t value, PretenureFlag pretenure) {
- if (Smi::IsValid(value)) return Smi::FromInt(value);
- // Bypass NumberFromDouble to avoid various redundant checks.
- return AllocateHeapNumber(FastI2D(value), pretenure);
-}
-
-
-MaybeObject* Heap::NumberFromUint32(
- uint32_t value, PretenureFlag pretenure) {
- if (static_cast<int32_t>(value) >= 0 &&
- Smi::IsValid(static_cast<int32_t>(value))) {
- return Smi::FromInt(static_cast<int32_t>(value));
- }
- // Bypass NumberFromDouble to avoid various redundant checks.
- return AllocateHeapNumber(FastUI2D(value), pretenure);
+ return allocation;
}
@@ -453,6 +400,8 @@ bool Heap::AllowedToBeMigrated(HeapObject* obj, AllocationSpace dst) {
case PROPERTY_CELL_SPACE:
case LO_SPACE:
return false;
+ case INVALID_SPACE:
+ break;
}
UNREACHABLE();
return false;
@@ -490,33 +439,51 @@ void Heap::ScavengePointer(HeapObject** p) {
}
-void Heap::UpdateAllocationSiteFeedback(HeapObject* object,
- ScratchpadSlotMode mode) {
- Heap* heap = object->GetHeap();
- ASSERT(heap->InFromSpace(object));
-
- if (!FLAG_allocation_site_pretenuring ||
- !AllocationSite::CanTrack(object->map()->instance_type())) return;
-
+AllocationMemento* Heap::FindAllocationMemento(HeapObject* object) {
// Check if there is potentially a memento behind the object. If
// the last word of the momento is on another page we return
- // immediatelly. Note that we do not have to compare with the current
- // top pointer of the from space page, since we always install filler
- // objects above the top pointer of a from space page when performing
- // a garbage collection.
+ // immediately.
Address object_address = object->address();
Address memento_address = object_address + object->Size();
Address last_memento_word_address = memento_address + kPointerSize;
if (!NewSpacePage::OnSamePage(object_address,
last_memento_word_address)) {
- return;
+ return NULL;
}
HeapObject* candidate = HeapObject::FromAddress(memento_address);
- if (candidate->map() != heap->allocation_memento_map()) return;
+ if (candidate->map() != allocation_memento_map()) return NULL;
+
+ // Either the object is the last object in the new space, or there is another
+ // object of at least word size (the header map word) following it, so
+ // suffices to compare ptr and top here. Note that technically we do not have
+ // to compare with the current top pointer of the from space page during GC,
+ // since we always install filler objects above the top pointer of a from
+ // space page when performing a garbage collection. However, always performing
+ // the test makes it possible to have a single, unified version of
+ // FindAllocationMemento that is used both by the GC and the mutator.
+ Address top = NewSpaceTop();
+ ASSERT(memento_address == top ||
+ memento_address + HeapObject::kHeaderSize <= top ||
+ !NewSpacePage::OnSamePage(memento_address, top));
+ if (memento_address == top) return NULL;
AllocationMemento* memento = AllocationMemento::cast(candidate);
- if (!memento->IsValid()) return;
+ if (!memento->IsValid()) return NULL;
+ return memento;
+}
+
+
+void Heap::UpdateAllocationSiteFeedback(HeapObject* object,
+ ScratchpadSlotMode mode) {
+ Heap* heap = object->GetHeap();
+ ASSERT(heap->InFromSpace(object));
+
+ if (!FLAG_allocation_site_pretenuring ||
+ !AllocationSite::CanTrack(object->map()->instance_type())) return;
+
+ AllocationMemento* memento = heap->FindAllocationMemento(object);
+ if (memento == NULL) return;
if (memento->GetAllocationSite()->IncrementMementoFoundCount()) {
heap->AddAllocationSiteToScratchpad(memento->GetAllocationSite(), mode);
@@ -560,25 +527,6 @@ bool Heap::CollectGarbage(AllocationSpace space,
}
-MaybeObject* Heap::PrepareForCompare(String* str) {
- // Always flatten small strings and force flattening of long strings
- // after we have accumulated a certain amount we failed to flatten.
- static const int kMaxAlwaysFlattenLength = 32;
- static const int kFlattenLongThreshold = 16*KB;
-
- const int length = str->length();
- MaybeObject* obj = str->TryFlatten();
- if (length <= kMaxAlwaysFlattenLength ||
- unflattened_strings_length_ >= kFlattenLongThreshold) {
- return obj;
- }
- if (obj->IsFailure()) {
- unflattened_strings_length_ += length;
- }
- return str;
-}
-
-
int64_t Heap::AdjustAmountOfExternalAllocatedMemory(
int64_t change_in_bytes) {
ASSERT(HasBeenSetUp());
@@ -627,13 +575,6 @@ Isolate* Heap::isolate() {
}
-#ifdef DEBUG
-#define GC_GREEDY_CHECK(ISOLATE) \
- if (FLAG_gc_greedy) (ISOLATE)->heap()->GarbageCollectionGreedyCheck()
-#else
-#define GC_GREEDY_CHECK(ISOLATE) { }
-#endif
-
// Calls the FUNCTION_CALL function and retries it up to three times
// to guarantee that any allocations performed during the call will
// succeed if there's enough memory.
@@ -641,30 +582,31 @@ Isolate* Heap::isolate() {
// Warning: Do not use the identifiers __object__, __maybe_object__ or
// __scope__ in a call to this macro.
+#define RETURN_OBJECT_UNLESS_EXCEPTION(ISOLATE, RETURN_VALUE, RETURN_EMPTY) \
+ if (!__allocation__.IsRetry()) { \
+ __object__ = __allocation__.ToObjectChecked(); \
+ if (__object__ == (ISOLATE)->heap()->exception()) { RETURN_EMPTY; } \
+ RETURN_VALUE; \
+ }
+
#define CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY) \
do { \
- GC_GREEDY_CHECK(ISOLATE); \
- MaybeObject* __maybe_object__ = FUNCTION_CALL; \
+ AllocationResult __allocation__ = FUNCTION_CALL; \
Object* __object__ = NULL; \
- if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \
- if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \
- (ISOLATE)->heap()->CollectGarbage(Failure::cast(__maybe_object__)-> \
- allocation_space(), \
- "allocation failure"); \
- __maybe_object__ = FUNCTION_CALL; \
- if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \
- if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \
+ RETURN_OBJECT_UNLESS_EXCEPTION(ISOLATE, RETURN_VALUE, RETURN_EMPTY) \
+ (ISOLATE)->heap()->CollectGarbage(__allocation__.RetrySpace(), \
+ "allocation failure"); \
+ __allocation__ = FUNCTION_CALL; \
+ RETURN_OBJECT_UNLESS_EXCEPTION(ISOLATE, RETURN_VALUE, RETURN_EMPTY) \
(ISOLATE)->counters()->gc_last_resort_from_handles()->Increment(); \
(ISOLATE)->heap()->CollectAllAvailableGarbage("last resort gc"); \
{ \
AlwaysAllocateScope __scope__(ISOLATE); \
- __maybe_object__ = FUNCTION_CALL; \
+ __allocation__ = FUNCTION_CALL; \
} \
- if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \
- if (__maybe_object__->IsRetryAfterGC()) { \
+ RETURN_OBJECT_UNLESS_EXCEPTION(ISOLATE, RETURN_VALUE, RETURN_EMPTY) \
/* TODO(1181417): Fix this. */ \
- v8::internal::Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true);\
- } \
+ v8::internal::Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); \
RETURN_EMPTY; \
} while (false)
@@ -687,13 +629,6 @@ Isolate* Heap::isolate() {
CALL_AND_RETRY_OR_DIE(ISOLATE, FUNCTION_CALL, return, return)
-#define CALL_HEAP_FUNCTION_PASS_EXCEPTION(ISOLATE, FUNCTION_CALL) \
- CALL_AND_RETRY(ISOLATE, \
- FUNCTION_CALL, \
- return __object__, \
- return __maybe_object__)
-
-
void ExternalStringTable::AddString(String* string) {
ASSERT(string->IsExternalString());
if (heap_->InNewSpace(string)) {
diff --git a/deps/v8/src/heap-profiler.cc b/deps/v8/src/heap-profiler.cc
index 1dc1113214..6068bf43bd 100644
--- a/deps/v8/src/heap-profiler.cc
+++ b/deps/v8/src/heap-profiler.cc
@@ -1,29 +1,6 @@
// Copyright 2009-2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/heap-profiler.h b/deps/v8/src/heap-profiler.h
index e4838df136..6fdfd955ec 100644
--- a/deps/v8/src/heap-profiler.h
+++ b/deps/v8/src/heap-profiler.h
@@ -1,29 +1,6 @@
// Copyright 2009-2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HEAP_PROFILER_H_
#define V8_HEAP_PROFILER_H_
diff --git a/deps/v8/src/heap-snapshot-generator-inl.h b/deps/v8/src/heap-snapshot-generator-inl.h
index 582de32c2b..90f3b1bc1b 100644
--- a/deps/v8/src/heap-snapshot-generator-inl.h
+++ b/deps/v8/src/heap-snapshot-generator-inl.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HEAP_SNAPSHOT_GENERATOR_INL_H_
#define V8_HEAP_SNAPSHOT_GENERATOR_INL_H_
diff --git a/deps/v8/src/heap-snapshot-generator.cc b/deps/v8/src/heap-snapshot-generator.cc
index 332d0dbf6f..cafee77b4c 100644
--- a/deps/v8/src/heap-snapshot-generator.cc
+++ b/deps/v8/src/heap-snapshot-generator.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -31,10 +8,10 @@
#include "allocation-tracker.h"
#include "code-stubs.h"
-#include "heap-profiler.h"
+#include "conversions.h"
#include "debug.h"
+#include "heap-profiler.h"
#include "types.h"
-#include "v8conversions.h"
namespace v8 {
namespace internal {
@@ -732,7 +709,7 @@ size_t HeapObjectsMap::GetUsedMemorySize() const {
HeapEntriesMap::HeapEntriesMap()
- : entries_(HeapThingsMatch) {
+ : entries_(HashMap::PointersMatch) {
}
@@ -751,7 +728,7 @@ void HeapEntriesMap::Pair(HeapThing thing, int entry) {
HeapObjectsSet::HeapObjectsSet()
- : entries_(HeapEntriesMap::HeapThingsMatch) {
+ : entries_(HashMap::PointersMatch) {
}
@@ -1079,21 +1056,30 @@ class IndexedReferencesExtractor : public ObjectVisitor {
static void MarkVisitedField(HeapObject* obj, int offset) {
if (offset < 0) return;
Address field = obj->address() + offset;
- ASSERT(!Memory::Object_at(field)->IsFailure());
ASSERT(Memory::Object_at(field)->IsHeapObject());
- *field |= kFailureTag;
+ intptr_t p = reinterpret_cast<intptr_t>(Memory::Object_at(field));
+ ASSERT(!IsMarked(p));
+ intptr_t p_tagged = p | kTag;
+ Memory::Object_at(field) = reinterpret_cast<Object*>(p_tagged);
}
private:
bool CheckVisitedAndUnmark(Object** field) {
- if ((*field)->IsFailure()) {
- intptr_t untagged = reinterpret_cast<intptr_t>(*field) & ~kFailureTagMask;
- *field = reinterpret_cast<Object*>(untagged | kHeapObjectTag);
+ intptr_t p = reinterpret_cast<intptr_t>(*field);
+ if (IsMarked(p)) {
+ intptr_t p_untagged = (p & ~kTaggingMask) | kHeapObjectTag;
+ *field = reinterpret_cast<Object*>(p_untagged);
ASSERT((*field)->IsHeapObject());
return true;
}
return false;
}
+
+ static const intptr_t kTaggingMask = 3;
+ static const intptr_t kTag = 3;
+
+ static bool IsMarked(intptr_t p) { return (p & kTaggingMask) == kTag; }
+
V8HeapExplorer* generator_;
HeapObject* parent_obj_;
int parent_;
@@ -1101,10 +1087,8 @@ class IndexedReferencesExtractor : public ObjectVisitor {
};
-void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
- HeapEntry* heap_entry = GetEntry(obj);
- if (heap_entry == NULL) return; // No interest in this object.
- int entry = heap_entry->index();
+bool V8HeapExplorer::ExtractReferencesPass1(int entry, HeapObject* obj) {
+ if (obj->IsFixedArray()) return false; // FixedArrays are processed on pass 2
if (obj->IsJSGlobalProxy()) {
ExtractJSGlobalProxyReferences(entry, JSGlobalProxy::cast(obj));
@@ -1114,8 +1098,6 @@ void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
ExtractJSObjectReferences(entry, JSObject::cast(obj));
} else if (obj->IsString()) {
ExtractStringReferences(entry, String::cast(obj));
- } else if (obj->IsContext()) {
- ExtractContextReferences(entry, Context::cast(obj));
} else if (obj->IsMap()) {
ExtractMapReferences(entry, Map::cast(obj));
} else if (obj->IsSharedFunctionInfo()) {
@@ -1137,12 +1119,19 @@ void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
} else if (obj->IsAllocationSite()) {
ExtractAllocationSiteReferences(entry, AllocationSite::cast(obj));
}
- SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
+ return true;
+}
+
- // Extract unvisited fields as hidden references and restore tags
- // of visited fields.
- IndexedReferencesExtractor refs_extractor(this, obj, entry);
- obj->Iterate(&refs_extractor);
+bool V8HeapExplorer::ExtractReferencesPass2(int entry, HeapObject* obj) {
+ if (!obj->IsFixedArray()) return false;
+
+ if (obj->IsContext()) {
+ ExtractContextReferences(entry, Context::cast(obj));
+ } else {
+ ExtractFixedArrayReferences(entry, FixedArray::cast(obj));
+ }
+ return true;
}
@@ -1319,6 +1308,22 @@ void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) {
TagObject(back_pointer, "(back pointer)");
SetInternalReference(transitions, transitions_entry,
"back_pointer", back_pointer);
+
+ if (FLAG_collect_maps && map->CanTransition()) {
+ if (!transitions->IsSimpleTransition()) {
+ if (transitions->HasPrototypeTransitions()) {
+ FixedArray* prototype_transitions =
+ transitions->GetPrototypeTransitions();
+ MarkAsWeakContainer(prototype_transitions);
+ TagObject(prototype_transitions, "(prototype transitions");
+ SetInternalReference(transitions, transitions_entry,
+ "prototype_transitions", prototype_transitions);
+ }
+ // TODO(alph): transitions keys are strong links.
+ MarkAsWeakContainer(transitions);
+ }
+ }
+
TagObject(transitions, "(transition array)");
SetInternalReference(map, entry,
"transitions", transitions,
@@ -1336,6 +1341,7 @@ void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) {
"descriptors", descriptors,
Map::kDescriptorsOffset);
+ MarkAsWeakContainer(map->code_cache());
SetInternalReference(map, entry,
"code_cache", map->code_cache(),
Map::kCodeCacheOffset);
@@ -1345,6 +1351,7 @@ void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) {
"constructor", map->constructor(),
Map::kConstructorOffset);
TagObject(map->dependent_code(), "(dependent code)");
+ MarkAsWeakContainer(map->dependent_code());
SetInternalReference(map, entry,
"dependent_code", map->dependent_code(),
Map::kDependentCodeOffset);
@@ -1399,6 +1406,9 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
SetInternalReference(obj, entry,
"optimized_code_map", shared->optimized_code_map(),
SharedFunctionInfo::kOptimizedCodeMapOffset);
+ SetInternalReference(obj, entry,
+ "feedback_vector", shared->feedback_vector(),
+ SharedFunctionInfo::kFeedbackVectorOffset);
SetWeakReference(obj, entry,
"initial_map", shared->initial_map(),
SharedFunctionInfo::kInitialMapOffset);
@@ -1506,6 +1516,7 @@ void V8HeapExplorer::ExtractPropertyCellReferences(int entry,
ExtractCellReferences(entry, cell);
SetInternalReference(cell, entry, "type", cell->type(),
PropertyCell::kTypeOffset);
+ MarkAsWeakContainer(cell->dependent_code());
SetInternalReference(cell, entry, "dependent_code", cell->dependent_code(),
PropertyCell::kDependentCodeOffset);
}
@@ -1517,6 +1528,7 @@ void V8HeapExplorer::ExtractAllocationSiteReferences(int entry,
AllocationSite::kTransitionInfoOffset);
SetInternalReference(site, entry, "nested_site", site->nested_site(),
AllocationSite::kNestedSiteOffset);
+ MarkAsWeakContainer(site->dependent_code());
SetInternalReference(site, entry, "dependent_code", site->dependent_code(),
AllocationSite::kDependentCodeOffset);
// Do not visit weak_next as it is not visited by the StaticVisitor,
@@ -1562,6 +1574,20 @@ void V8HeapExplorer::ExtractJSArrayBufferReferences(
}
+void V8HeapExplorer::ExtractFixedArrayReferences(int entry, FixedArray* array) {
+ bool is_weak = weak_containers_.Contains(array);
+ for (int i = 0, l = array->length(); i < l; ++i) {
+ if (is_weak) {
+ SetWeakReference(array, entry,
+ i, array->get(i), array->OffsetOfElementAt(i));
+ } else {
+ SetInternalReference(array, entry,
+ i, array->get(i), array->OffsetOfElementAt(i));
+ }
+ }
+}
+
+
void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, int entry) {
if (!js_obj->IsJSFunction()) return;
@@ -1634,7 +1660,6 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
case HANDLER: // only in lookup results, not in descriptors
case INTERCEPTOR: // only in lookup results, not in descriptors
break;
- case TRANSITION:
case NONEXISTENT:
UNREACHABLE();
break;
@@ -1725,8 +1750,10 @@ String* V8HeapExplorer::GetConstructorName(JSObject* object) {
// return its name. This is for instances of binding objects, which
// have prototype constructor type "Object".
Object* constructor_prop = NULL;
- LookupResult result(heap->isolate());
- object->LocalLookupRealNamedProperty(heap->constructor_string(), &result);
+ Isolate* isolate = heap->isolate();
+ LookupResult result(isolate);
+ object->LocalLookupRealNamedProperty(
+ isolate->factory()->constructor_string(), &result);
if (!result.IsFound()) return object->constructor_name();
constructor_prop = result.GetLazyValue();
@@ -1833,6 +1860,25 @@ bool V8HeapExplorer::IterateAndExtractReferences(
heap_->IterateRoots(&extractor, VISIT_ALL);
extractor.FillReferences(this);
+ // We have to do two passes as sometimes FixedArrays are used
+ // to weakly hold their items, and it's impossible to distinguish
+ // between these cases without processing the array owner first.
+ bool interrupted =
+ IterateAndExtractSinglePass<&V8HeapExplorer::ExtractReferencesPass1>() ||
+ IterateAndExtractSinglePass<&V8HeapExplorer::ExtractReferencesPass2>();
+
+ if (interrupted) {
+ filler_ = NULL;
+ return false;
+ }
+
+ filler_ = NULL;
+ return progress_->ProgressReport(true);
+}
+
+
+template<V8HeapExplorer::ExtractReferencesMethod extractor>
+bool V8HeapExplorer::IterateAndExtractSinglePass() {
// Now iterate the whole heap.
bool interrupted = false;
HeapIterator iterator(heap_, HeapIterator::kFilterUnreachable);
@@ -1840,18 +1886,22 @@ bool V8HeapExplorer::IterateAndExtractReferences(
for (HeapObject* obj = iterator.next();
obj != NULL;
obj = iterator.next(), progress_->ProgressStep()) {
- if (!interrupted) {
- ExtractReferences(obj);
- if (!progress_->ProgressReport(false)) interrupted = true;
+ if (interrupted) continue;
+
+ HeapEntry* heap_entry = GetEntry(obj);
+ int entry = heap_entry->index();
+ if ((this->*extractor)(entry, obj)) {
+ SetInternalReference(obj, entry,
+ "map", obj->map(), HeapObject::kMapOffset);
+ // Extract unvisited fields as hidden references and restore tags
+ // of visited fields.
+ IndexedReferencesExtractor refs_extractor(this, obj, entry);
+ obj->Iterate(&refs_extractor);
}
- }
- if (interrupted) {
- filler_ = NULL;
- return false;
- }
- filler_ = NULL;
- return progress_->ProgressReport(true);
+ if (!progress_->ProgressReport(false)) interrupted = true;
+ }
+ return interrupted;
}
@@ -1987,6 +2037,24 @@ void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj,
}
+void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj,
+ int parent_entry,
+ int index,
+ Object* child_obj,
+ int field_offset) {
+ ASSERT(parent_entry == GetEntry(parent_obj)->index());
+ HeapEntry* child_entry = GetEntry(child_obj);
+ if (child_entry == NULL) return;
+ if (IsEssentialObject(child_obj)) {
+ filler_->SetNamedReference(HeapGraphEdge::kWeak,
+ parent_entry,
+ names_->GetFormatted("%d", index),
+ child_entry);
+ }
+ IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
+}
+
+
void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
int parent_entry,
Name* reference_name,
@@ -2072,9 +2140,7 @@ void V8HeapExplorer::SetGcSubrootReference(
GlobalObject* global = context->global_object();
if (global->IsJSGlobalObject()) {
bool is_debug_object = false;
-#ifdef ENABLE_DEBUGGER_SUPPORT
is_debug_object = heap_->isolate()->debug()->IsDebugGlobal(global);
-#endif
if (!is_debug_object && !user_roots_.Contains(global)) {
user_roots_.Insert(global);
SetUserGlobalReference(global);
@@ -2114,6 +2180,13 @@ void V8HeapExplorer::TagObject(Object* obj, const char* tag) {
}
+void V8HeapExplorer::MarkAsWeakContainer(Object* object) {
+ if (IsEssentialObject(object) && object->IsFixedArray()) {
+ weak_containers_.Insert(object);
+ }
+}
+
+
class GlobalObjectsEnumerator : public ObjectVisitor {
public:
virtual void VisitPointers(Object** start, Object** end) {
@@ -2504,7 +2577,7 @@ bool HeapSnapshotGenerator::GenerateSnapshot() {
debug_heap->Verify();
#endif
- SetProgressTotal(1); // 1 pass.
+ SetProgressTotal(2); // 2 passes.
#ifdef VERIFY_HEAP
debug_heap->Verify();
diff --git a/deps/v8/src/heap-snapshot-generator.h b/deps/v8/src/heap-snapshot-generator.h
index 634ede19ab..a0f2a6293c 100644
--- a/deps/v8/src/heap-snapshot-generator.h
+++ b/deps/v8/src/heap-snapshot-generator.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HEAP_SNAPSHOT_GENERATOR_H_
#define V8_HEAP_SNAPSHOT_GENERATOR_H_
@@ -315,9 +292,6 @@ class HeapEntriesMap {
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(thing)),
v8::internal::kZeroHashSeed);
}
- static bool HeapThingsMatch(HeapThing key1, HeapThing key2) {
- return key1 == key2;
- }
HashMap entries_;
@@ -376,6 +350,9 @@ class V8HeapExplorer : public HeapEntriesAllocator {
static HeapObject* const kInternalRootObject;
private:
+ typedef bool (V8HeapExplorer::*ExtractReferencesMethod)(int entry,
+ HeapObject* object);
+
HeapEntry* AddEntry(HeapObject* object);
HeapEntry* AddEntry(HeapObject* object,
HeapEntry::Type type,
@@ -383,7 +360,11 @@ class V8HeapExplorer : public HeapEntriesAllocator {
const char* GetSystemEntryName(HeapObject* object);
- void ExtractReferences(HeapObject* obj);
+ template<V8HeapExplorer::ExtractReferencesMethod extractor>
+ bool IterateAndExtractSinglePass();
+
+ bool ExtractReferencesPass1(int entry, HeapObject* obj);
+ bool ExtractReferencesPass2(int entry, HeapObject* obj);
void ExtractJSGlobalProxyReferences(int entry, JSGlobalProxy* proxy);
void ExtractJSObjectReferences(int entry, JSObject* js_obj);
void ExtractStringReferences(int entry, String* obj);
@@ -400,12 +381,14 @@ class V8HeapExplorer : public HeapEntriesAllocator {
void ExtractPropertyCellReferences(int entry, PropertyCell* cell);
void ExtractAllocationSiteReferences(int entry, AllocationSite* site);
void ExtractJSArrayBufferReferences(int entry, JSArrayBuffer* buffer);
+ void ExtractFixedArrayReferences(int entry, FixedArray* array);
void ExtractClosureReferences(JSObject* js_obj, int entry);
void ExtractPropertyReferences(JSObject* js_obj, int entry);
bool ExtractAccessorPairProperty(JSObject* js_obj, int entry,
Object* key, Object* callback_obj);
void ExtractElementReferences(JSObject* js_obj, int entry);
void ExtractInternalReferences(JSObject* js_obj, int entry);
+
bool IsEssentialObject(Object* object);
void SetContextReference(HeapObject* parent_obj,
int parent,
@@ -439,6 +422,11 @@ class V8HeapExplorer : public HeapEntriesAllocator {
const char* reference_name,
Object* child_obj,
int field_offset);
+ void SetWeakReference(HeapObject* parent_obj,
+ int parent,
+ int index,
+ Object* child_obj,
+ int field_offset);
void SetPropertyReference(HeapObject* parent_obj,
int parent,
Name* reference_name,
@@ -452,6 +440,7 @@ class V8HeapExplorer : public HeapEntriesAllocator {
VisitorSynchronization::SyncTag tag, bool is_weak, Object* child);
const char* GetStrongGcSubrootName(Object* object);
void TagObject(Object* obj, const char* tag);
+ void MarkAsWeakContainer(Object* object);
HeapEntry* GetEntry(Object* obj);
@@ -467,6 +456,7 @@ class V8HeapExplorer : public HeapEntriesAllocator {
HeapObjectsSet objects_tags_;
HeapObjectsSet strong_gc_subroot_names_;
HeapObjectsSet user_roots_;
+ HeapObjectsSet weak_containers_;
v8::HeapProfiler::ObjectNameResolver* global_object_name_resolver_;
static HeapObject* const kGcRootsObject;
diff --git a/deps/v8/src/heap.cc b/deps/v8/src/heap.cc
index 6374433bbd..13771e613e 100644
--- a/deps/v8/src/heap.cc
+++ b/deps/v8/src/heap.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -32,6 +9,7 @@
#include "bootstrapper.h"
#include "codegen.h"
#include "compilation-cache.h"
+#include "conversions.h"
#include "cpu-profiler.h"
#include "debug.h"
#include "deoptimizer.h"
@@ -49,9 +27,8 @@
#include "snapshot.h"
#include "store-buffer.h"
#include "utils/random-number-generator.h"
-#include "v8conversions.h"
+#include "utils.h"
#include "v8threads.h"
-#include "v8utils.h"
#include "vm-state-inl.h"
#if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP
#include "regexp-macro-assembler.h"
@@ -68,7 +45,7 @@ namespace internal {
Heap::Heap()
: isolate_(NULL),
- code_range_size_(kIs64BitArch ? 512 * MB : 0),
+ code_range_size_(0),
// semispace_size_ should be a power of 2 and old_generation_size_ should be
// a multiple of Page::kPageSize.
reserved_semispace_size_(8 * (kPointerSize / 4) * MB),
@@ -81,6 +58,7 @@ Heap::Heap()
// Will be 4 * reserved_semispace_size_ to ensure that young
// generation can be aligned to its size.
maximum_committed_(0),
+ old_space_growing_factor_(4),
survived_since_last_expansion_(0),
sweep_generation_(0),
always_allocate_scope_depth_(0),
@@ -165,15 +143,6 @@ Heap::Heap()
// Ensure old_generation_size_ is a multiple of kPageSize.
ASSERT(MB >= Page::kPageSize);
- intptr_t max_virtual = OS::MaxVirtualMemory();
-
- if (max_virtual > 0) {
- if (code_range_size_ > 0) {
- // Reserve no more than 1/8 of the memory for the code range.
- code_range_size_ = Min(code_range_size_, max_virtual >> 3);
- }
- }
-
memset(roots_, 0, sizeof(roots_[0]) * kRootListLength);
native_contexts_list_ = NULL;
array_buffers_list_ = Smi::FromInt(0);
@@ -719,12 +688,10 @@ void Heap::GarbageCollectionEpilogue() {
#undef UPDATE_FRAGMENTATION_FOR_SPACE
#undef UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE
-#if defined(DEBUG)
+#ifdef DEBUG
ReportStatisticsAfterGC();
#endif // DEBUG
-#ifdef ENABLE_DEBUGGER_SUPPORT
isolate_->debug()->AfterGarbageCollection();
-#endif // ENABLE_DEBUGGER_SUPPORT
}
@@ -947,14 +914,14 @@ void Heap::ReserveSpace(int *sizes, Address *locations_out) {
ASSERT(NEW_SPACE == FIRST_PAGED_SPACE - 1);
for (int space = NEW_SPACE; space <= LAST_PAGED_SPACE; space++) {
if (sizes[space] != 0) {
- MaybeObject* allocation;
+ AllocationResult allocation;
if (space == NEW_SPACE) {
allocation = new_space()->AllocateRaw(sizes[space]);
} else {
allocation = paged_space(space)->AllocateRaw(sizes[space]);
}
FreeListNode* node;
- if (!allocation->To<FreeListNode>(&node)) {
+ if (!allocation.To(&node)) {
if (space == NEW_SPACE) {
Heap::CollectGarbage(NEW_SPACE,
"failed to reserve space in the new space");
@@ -1527,9 +1494,6 @@ void Heap::Scavenge() {
incremental_marking()->PrepareForScavenge();
- paged_space(OLD_DATA_SPACE)->EnsureSweeperProgress(new_space_.Size());
- paged_space(OLD_POINTER_SPACE)->EnsureSweeperProgress(new_space_.Size());
-
// Flip the semispaces. After flipping, to space is empty, from space has
// live objects.
new_space_.Flip();
@@ -1719,180 +1683,6 @@ void Heap::UpdateReferencesInExternalStringTable(
}
-template <class T>
-struct WeakListVisitor;
-
-
-template <class T>
-static Object* VisitWeakList(Heap* heap,
- Object* list,
- WeakObjectRetainer* retainer,
- bool record_slots) {
- Object* undefined = heap->undefined_value();
- Object* head = undefined;
- T* tail = NULL;
- MarkCompactCollector* collector = heap->mark_compact_collector();
- while (list != undefined) {
- // Check whether to keep the candidate in the list.
- T* candidate = reinterpret_cast<T*>(list);
- Object* retained = retainer->RetainAs(list);
- if (retained != NULL) {
- if (head == undefined) {
- // First element in the list.
- head = retained;
- } else {
- // Subsequent elements in the list.
- ASSERT(tail != NULL);
- WeakListVisitor<T>::SetWeakNext(tail, retained);
- if (record_slots) {
- Object** next_slot =
- HeapObject::RawField(tail, WeakListVisitor<T>::WeakNextOffset());
- collector->RecordSlot(next_slot, next_slot, retained);
- }
- }
- // Retained object is new tail.
- ASSERT(!retained->IsUndefined());
- candidate = reinterpret_cast<T*>(retained);
- tail = candidate;
-
-
- // tail is a live object, visit it.
- WeakListVisitor<T>::VisitLiveObject(
- heap, tail, retainer, record_slots);
- } else {
- WeakListVisitor<T>::VisitPhantomObject(heap, candidate);
- }
-
- // Move to next element in the list.
- list = WeakListVisitor<T>::WeakNext(candidate);
- }
-
- // Terminate the list if there is one or more elements.
- if (tail != NULL) {
- WeakListVisitor<T>::SetWeakNext(tail, undefined);
- }
- return head;
-}
-
-
-template <class T>
-static void ClearWeakList(Heap* heap,
- Object* list) {
- Object* undefined = heap->undefined_value();
- while (list != undefined) {
- T* candidate = reinterpret_cast<T*>(list);
- list = WeakListVisitor<T>::WeakNext(candidate);
- WeakListVisitor<T>::SetWeakNext(candidate, undefined);
- }
-}
-
-
-template<>
-struct WeakListVisitor<JSFunction> {
- static void SetWeakNext(JSFunction* function, Object* next) {
- function->set_next_function_link(next);
- }
-
- static Object* WeakNext(JSFunction* function) {
- return function->next_function_link();
- }
-
- static int WeakNextOffset() {
- return JSFunction::kNextFunctionLinkOffset;
- }
-
- static void VisitLiveObject(Heap*, JSFunction*,
- WeakObjectRetainer*, bool) {
- }
-
- static void VisitPhantomObject(Heap*, JSFunction*) {
- }
-};
-
-
-template<>
-struct WeakListVisitor<Code> {
- static void SetWeakNext(Code* code, Object* next) {
- code->set_next_code_link(next);
- }
-
- static Object* WeakNext(Code* code) {
- return code->next_code_link();
- }
-
- static int WeakNextOffset() {
- return Code::kNextCodeLinkOffset;
- }
-
- static void VisitLiveObject(Heap*, Code*,
- WeakObjectRetainer*, bool) {
- }
-
- static void VisitPhantomObject(Heap*, Code*) {
- }
-};
-
-
-template<>
-struct WeakListVisitor<Context> {
- static void SetWeakNext(Context* context, Object* next) {
- context->set(Context::NEXT_CONTEXT_LINK,
- next,
- UPDATE_WRITE_BARRIER);
- }
-
- static Object* WeakNext(Context* context) {
- return context->get(Context::NEXT_CONTEXT_LINK);
- }
-
- static void VisitLiveObject(Heap* heap,
- Context* context,
- WeakObjectRetainer* retainer,
- bool record_slots) {
- // Process the three weak lists linked off the context.
- DoWeakList<JSFunction>(heap, context, retainer, record_slots,
- Context::OPTIMIZED_FUNCTIONS_LIST);
- DoWeakList<Code>(heap, context, retainer, record_slots,
- Context::OPTIMIZED_CODE_LIST);
- DoWeakList<Code>(heap, context, retainer, record_slots,
- Context::DEOPTIMIZED_CODE_LIST);
- }
-
- template<class T>
- static void DoWeakList(Heap* heap,
- Context* context,
- WeakObjectRetainer* retainer,
- bool record_slots,
- int index) {
- // Visit the weak list, removing dead intermediate elements.
- Object* list_head = VisitWeakList<T>(heap, context->get(index), retainer,
- record_slots);
-
- // Update the list head.
- context->set(index, list_head, UPDATE_WRITE_BARRIER);
-
- if (record_slots) {
- // Record the updated slot if necessary.
- Object** head_slot = HeapObject::RawField(
- context, FixedArray::SizeFor(index));
- heap->mark_compact_collector()->RecordSlot(
- head_slot, head_slot, list_head);
- }
- }
-
- static void VisitPhantomObject(Heap* heap, Context* context) {
- ClearWeakList<JSFunction>(heap,
- context->get(Context::OPTIMIZED_FUNCTIONS_LIST));
- ClearWeakList<Code>(heap, context->get(Context::OPTIMIZED_CODE_LIST));
- ClearWeakList<Code>(heap, context->get(Context::DEOPTIMIZED_CODE_LIST));
- }
-
- static int WeakNextOffset() {
- return FixedArray::SizeFor(Context::NEXT_CONTEXT_LINK);
- }
-};
-
-
void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) {
// We don't record weak slots during marking or scavenges.
// Instead we do it once when we complete mark-compact cycle.
@@ -1918,66 +1708,6 @@ void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer,
}
-template<>
-struct WeakListVisitor<JSArrayBufferView> {
- static void SetWeakNext(JSArrayBufferView* obj, Object* next) {
- obj->set_weak_next(next);
- }
-
- static Object* WeakNext(JSArrayBufferView* obj) {
- return obj->weak_next();
- }
-
- static void VisitLiveObject(Heap*,
- JSArrayBufferView* obj,
- WeakObjectRetainer* retainer,
- bool record_slots) {}
-
- static void VisitPhantomObject(Heap*, JSArrayBufferView*) {}
-
- static int WeakNextOffset() {
- return JSArrayBufferView::kWeakNextOffset;
- }
-};
-
-
-template<>
-struct WeakListVisitor<JSArrayBuffer> {
- static void SetWeakNext(JSArrayBuffer* obj, Object* next) {
- obj->set_weak_next(next);
- }
-
- static Object* WeakNext(JSArrayBuffer* obj) {
- return obj->weak_next();
- }
-
- static void VisitLiveObject(Heap* heap,
- JSArrayBuffer* array_buffer,
- WeakObjectRetainer* retainer,
- bool record_slots) {
- Object* typed_array_obj =
- VisitWeakList<JSArrayBufferView>(
- heap,
- array_buffer->weak_first_view(),
- retainer, record_slots);
- array_buffer->set_weak_first_view(typed_array_obj);
- if (typed_array_obj != heap->undefined_value() && record_slots) {
- Object** slot = HeapObject::RawField(
- array_buffer, JSArrayBuffer::kWeakFirstViewOffset);
- heap->mark_compact_collector()->RecordSlot(slot, slot, typed_array_obj);
- }
- }
-
- static void VisitPhantomObject(Heap* heap, JSArrayBuffer* phantom) {
- Runtime::FreeArrayBuffer(heap->isolate(), phantom);
- }
-
- static int WeakNextOffset() {
- return JSArrayBuffer::kWeakNextOffset;
- }
-};
-
-
void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer,
bool record_slots) {
Object* array_buffer_obj =
@@ -1999,29 +1729,6 @@ void Heap::TearDownArrayBuffers() {
}
-template<>
-struct WeakListVisitor<AllocationSite> {
- static void SetWeakNext(AllocationSite* obj, Object* next) {
- obj->set_weak_next(next);
- }
-
- static Object* WeakNext(AllocationSite* obj) {
- return obj->weak_next();
- }
-
- static void VisitLiveObject(Heap* heap,
- AllocationSite* site,
- WeakObjectRetainer* retainer,
- bool record_slots) {}
-
- static void VisitPhantomObject(Heap* heap, AllocationSite* phantom) {}
-
- static int WeakNextOffset() {
- return AllocationSite::kWeakNextOffset;
- }
-};
-
-
void Heap::ProcessAllocationSites(WeakObjectRetainer* retainer,
bool record_slots) {
Object* allocation_site_obj =
@@ -2338,20 +2045,18 @@ class ScavengingVisitor : public StaticVisitorBase {
Heap* heap = map->GetHeap();
if (heap->ShouldBePromoted(object->address(), object_size)) {
- MaybeObject* maybe_result;
+ AllocationResult allocation;
if (object_contents == DATA_OBJECT) {
ASSERT(heap->AllowedToBeMigrated(object, OLD_DATA_SPACE));
- maybe_result = heap->old_data_space()->AllocateRaw(allocation_size);
+ allocation = heap->old_data_space()->AllocateRaw(allocation_size);
} else {
ASSERT(heap->AllowedToBeMigrated(object, OLD_POINTER_SPACE));
- maybe_result = heap->old_pointer_space()->AllocateRaw(allocation_size);
+ allocation = heap->old_pointer_space()->AllocateRaw(allocation_size);
}
- Object* result = NULL; // Initialization to please compiler.
- if (maybe_result->ToObject(&result)) {
- HeapObject* target = HeapObject::cast(result);
-
+ HeapObject* target = NULL; // Initialization to please compiler.
+ if (allocation.To(&target)) {
if (alignment != kObjectAlignment) {
target = EnsureDoubleAligned(heap, target, allocation_size);
}
@@ -2376,10 +2081,10 @@ class ScavengingVisitor : public StaticVisitorBase {
}
}
ASSERT(heap->AllowedToBeMigrated(object, NEW_SPACE));
- MaybeObject* allocation = heap->new_space()->AllocateRaw(allocation_size);
+ AllocationResult allocation =
+ heap->new_space()->AllocateRaw(allocation_size);
heap->promotion_queue()->SetNewLimit(heap->new_space()->top());
- Object* result = allocation->ToObjectUnchecked();
- HeapObject* target = HeapObject::cast(result);
+ HeapObject* target = HeapObject::cast(allocation.ToObjectChecked());
if (alignment != kObjectAlignment) {
target = EnsureDoubleAligned(heap, target, allocation_size);
@@ -2616,11 +2321,11 @@ void Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) {
}
-MaybeObject* Heap::AllocatePartialMap(InstanceType instance_type,
- int instance_size) {
+AllocationResult Heap::AllocatePartialMap(InstanceType instance_type,
+ int instance_size) {
Object* result;
- MaybeObject* maybe_result = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE);
+ if (!allocation.To(&result)) return allocation;
// Map::cast cannot be used due to uninitialized map field.
reinterpret_cast<Map*>(result)->set_map(raw_unchecked_meta_map());
@@ -2640,15 +2345,15 @@ MaybeObject* Heap::AllocatePartialMap(InstanceType instance_type,
}
-MaybeObject* Heap::AllocateMap(InstanceType instance_type,
- int instance_size,
- ElementsKind elements_kind) {
- Object* result;
- MaybeObject* maybe_result = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE);
- if (!maybe_result->To(&result)) return maybe_result;
+AllocationResult Heap::AllocateMap(InstanceType instance_type,
+ int instance_size,
+ ElementsKind elements_kind) {
+ HeapObject* result;
+ AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE);
+ if (!allocation.To(&result)) return allocation;
- Map* map = reinterpret_cast<Map*>(result);
- map->set_map_no_write_barrier(meta_map());
+ result->set_map_no_write_barrier(meta_map());
+ Map* map = Map::cast(result);
map->set_instance_type(instance_type);
map->set_visitor_id(
StaticVisitorBase::GetVisitorId(instance_type, instance_size));
@@ -2674,52 +2379,19 @@ MaybeObject* Heap::AllocateMap(InstanceType instance_type,
}
-MaybeObject* Heap::AllocateCodeCache() {
- CodeCache* code_cache;
- { MaybeObject* maybe_code_cache = AllocateStruct(CODE_CACHE_TYPE);
- if (!maybe_code_cache->To(&code_cache)) return maybe_code_cache;
- }
- code_cache->set_default_cache(empty_fixed_array(), SKIP_WRITE_BARRIER);
- code_cache->set_normal_type_cache(undefined_value(), SKIP_WRITE_BARRIER);
- return code_cache;
-}
-
-
-MaybeObject* Heap::AllocatePolymorphicCodeCache() {
- return AllocateStruct(POLYMORPHIC_CODE_CACHE_TYPE);
-}
-
-
-MaybeObject* Heap::AllocateAccessorPair() {
- AccessorPair* accessors;
- { MaybeObject* maybe_accessors = AllocateStruct(ACCESSOR_PAIR_TYPE);
- if (!maybe_accessors->To(&accessors)) return maybe_accessors;
- }
- accessors->set_getter(the_hole_value(), SKIP_WRITE_BARRIER);
- accessors->set_setter(the_hole_value(), SKIP_WRITE_BARRIER);
- accessors->set_access_flags(Smi::FromInt(0), SKIP_WRITE_BARRIER);
- return accessors;
-}
-
-
-MaybeObject* Heap::AllocateTypeFeedbackInfo() {
- TypeFeedbackInfo* info;
- { MaybeObject* maybe_info = AllocateStruct(TYPE_FEEDBACK_INFO_TYPE);
- if (!maybe_info->To(&info)) return maybe_info;
+AllocationResult Heap::AllocateFillerObject(int size,
+ bool double_align,
+ AllocationSpace space) {
+ HeapObject* obj;
+ { AllocationResult allocation = AllocateRaw(size, space, space);
+ if (!allocation.To(&obj)) return allocation;
}
- info->initialize_storage();
- info->set_feedback_vector(empty_fixed_array(), SKIP_WRITE_BARRIER);
- return info;
-}
-
-
-MaybeObject* Heap::AllocateAliasedArgumentsEntry(int aliased_context_slot) {
- AliasedArgumentsEntry* entry;
- { MaybeObject* maybe_entry = AllocateStruct(ALIASED_ARGUMENTS_ENTRY_TYPE);
- if (!maybe_entry->To(&entry)) return maybe_entry;
- }
- entry->set_aliased_context_slot(aliased_context_slot);
- return entry;
+#ifdef DEBUG
+ MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
+ ASSERT(chunk->owner()->identity() == space);
+#endif
+ CreateFillerObjectAt(obj->address(), size);
+ return obj;
}
@@ -2748,60 +2420,62 @@ const Heap::StructTable Heap::struct_table[] = {
bool Heap::CreateInitialMaps() {
- Object* obj;
- { MaybeObject* maybe_obj = AllocatePartialMap(MAP_TYPE, Map::kSize);
- if (!maybe_obj->ToObject(&obj)) return false;
+ HeapObject* obj;
+ { AllocationResult allocation = AllocatePartialMap(MAP_TYPE, Map::kSize);
+ if (!allocation.To(&obj)) return false;
}
// Map::cast cannot be used due to uninitialized map field.
Map* new_meta_map = reinterpret_cast<Map*>(obj);
set_meta_map(new_meta_map);
new_meta_map->set_map(new_meta_map);
- { MaybeObject* maybe_obj =
- AllocatePartialMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_fixed_array_map(Map::cast(obj));
+ { // Partial map allocation
+#define ALLOCATE_PARTIAL_MAP(instance_type, size, field_name) \
+ { Map* map; \
+ if (!AllocatePartialMap((instance_type), (size)).To(&map)) return false; \
+ set_##field_name##_map(map); \
+ }
- { MaybeObject* maybe_obj = AllocatePartialMap(ODDBALL_TYPE, Oddball::kSize);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_oddball_map(Map::cast(obj));
+ ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel, fixed_array);
+ ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, undefined);
+ ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, null);
+ ALLOCATE_PARTIAL_MAP(CONSTANT_POOL_ARRAY_TYPE, kVariableSizeSentinel,
+ constant_pool_array);
- { MaybeObject* maybe_obj =
- AllocatePartialMap(CONSTANT_POOL_ARRAY_TYPE, kVariableSizeSentinel);
- if (!maybe_obj->ToObject(&obj)) return false;
+#undef ALLOCATE_PARTIAL_MAP
}
- set_constant_pool_array_map(Map::cast(obj));
// Allocate the empty array.
- { MaybeObject* maybe_obj = AllocateEmptyFixedArray();
- if (!maybe_obj->ToObject(&obj)) return false;
+ { AllocationResult allocation = AllocateEmptyFixedArray();
+ if (!allocation.To(&obj)) return false;
}
set_empty_fixed_array(FixedArray::cast(obj));
- { MaybeObject* maybe_obj = Allocate(oddball_map(), OLD_POINTER_SPACE);
- if (!maybe_obj->ToObject(&obj)) return false;
+ { AllocationResult allocation = Allocate(null_map(), OLD_POINTER_SPACE);
+ if (!allocation.To(&obj)) return false;
}
set_null_value(Oddball::cast(obj));
Oddball::cast(obj)->set_kind(Oddball::kNull);
- { MaybeObject* maybe_obj = Allocate(oddball_map(), OLD_POINTER_SPACE);
- if (!maybe_obj->ToObject(&obj)) return false;
+ { AllocationResult allocation = Allocate(undefined_map(), OLD_POINTER_SPACE);
+ if (!allocation.To(&obj)) return false;
}
set_undefined_value(Oddball::cast(obj));
Oddball::cast(obj)->set_kind(Oddball::kUndefined);
ASSERT(!InNewSpace(undefined_value()));
+ // Set preliminary exception sentinel value before actually initializing it.
+ set_exception(null_value());
+
// Allocate the empty descriptor array.
- { MaybeObject* maybe_obj = AllocateEmptyFixedArray();
- if (!maybe_obj->ToObject(&obj)) return false;
+ { AllocationResult allocation = AllocateEmptyFixedArray();
+ if (!allocation.To(&obj)) return false;
}
set_empty_descriptor_array(DescriptorArray::cast(obj));
// Allocate the constant pool array.
- { MaybeObject* maybe_obj = AllocateEmptyConstantPoolArray();
- if (!maybe_obj->ToObject(&obj)) return false;
+ { AllocationResult allocation = AllocateEmptyConstantPoolArray();
+ if (!allocation.To(&obj)) return false;
}
set_empty_constant_pool_array(ConstantPoolArray::cast(obj));
@@ -2817,10 +2491,15 @@ bool Heap::CreateInitialMaps() {
fixed_array_map()->init_back_pointer(undefined_value());
fixed_array_map()->set_instance_descriptors(empty_descriptor_array());
- oddball_map()->set_code_cache(empty_fixed_array());
- oddball_map()->set_dependent_code(DependentCode::cast(empty_fixed_array()));
- oddball_map()->init_back_pointer(undefined_value());
- oddball_map()->set_instance_descriptors(empty_descriptor_array());
+ undefined_map()->set_code_cache(empty_fixed_array());
+ undefined_map()->set_dependent_code(DependentCode::cast(empty_fixed_array()));
+ undefined_map()->init_back_pointer(undefined_value());
+ undefined_map()->set_instance_descriptors(empty_descriptor_array());
+
+ null_map()->set_code_cache(empty_fixed_array());
+ null_map()->set_dependent_code(DependentCode::cast(empty_fixed_array()));
+ null_map()->init_back_pointer(undefined_value());
+ null_map()->set_instance_descriptors(empty_descriptor_array());
constant_pool_array_map()->set_code_cache(empty_fixed_array());
constant_pool_array_map()->set_dependent_code(
@@ -2835,8 +2514,11 @@ bool Heap::CreateInitialMaps() {
fixed_array_map()->set_prototype(null_value());
fixed_array_map()->set_constructor(null_value());
- oddball_map()->set_prototype(null_value());
- oddball_map()->set_constructor(null_value());
+ undefined_map()->set_prototype(null_value());
+ undefined_map()->set_constructor(null_value());
+
+ null_map()->set_prototype(null_value());
+ null_map()->set_constructor(null_value());
constant_pool_array_map()->set_prototype(null_value());
constant_pool_array_map()->set_constructor(null_value());
@@ -2844,7 +2526,7 @@ bool Heap::CreateInitialMaps() {
{ // Map allocation
#define ALLOCATE_MAP(instance_type, size, field_name) \
{ Map* map; \
- if (!AllocateMap((instance_type), size)->To(&map)) return false; \
+ if (!AllocateMap((instance_type), size).To(&map)) return false; \
set_##field_name##_map(map); \
}
@@ -2859,12 +2541,24 @@ bool Heap::CreateInitialMaps() {
ALLOCATE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol)
ALLOCATE_MAP(FOREIGN_TYPE, Foreign::kSize, foreign)
+ ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, the_hole);
+ ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, boolean);
+ ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, uninitialized);
+ ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, arguments_marker);
+ ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, no_interceptor_result_sentinel);
+ ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, exception);
+ ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, termination_exception);
+
for (unsigned i = 0; i < ARRAY_SIZE(string_type_table); i++) {
const StringTypeTable& entry = string_type_table[i];
- { MaybeObject* maybe_obj = AllocateMap(entry.type, entry.size);
- if (!maybe_obj->ToObject(&obj)) return false;
+ { AllocationResult allocation = AllocateMap(entry.type, entry.size);
+ if (!allocation.To(&obj)) return false;
}
- roots_[entry.index] = Map::cast(obj);
+ // Mark cons string maps as unstable, because their objects can change
+ // maps during GC.
+ Map* map = Map::cast(obj);
+ if (StringShape(entry.type).IsCons()) map->mark_unstable();
+ roots_[entry.index] = map;
}
ALLOCATE_VARSIZE_MAP(STRING_TYPE, undetectable_string)
@@ -2904,12 +2598,13 @@ bool Heap::CreateInitialMaps() {
for (unsigned i = 0; i < ARRAY_SIZE(struct_table); i++) {
const StructTable& entry = struct_table[i];
Map* map;
- if (!AllocateMap(entry.type, entry.size)->To(&map))
+ if (!AllocateMap(entry.type, entry.size).To(&map))
return false;
roots_[entry.index] = map;
}
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, hash_table)
+ ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, ordered_hash_table)
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, function_context)
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, catch_context)
@@ -2937,13 +2632,13 @@ bool Heap::CreateInitialMaps() {
{ // Empty arrays
{ ByteArray* byte_array;
- if (!AllocateByteArray(0, TENURED)->To(&byte_array)) return false;
+ if (!AllocateByteArray(0, TENURED).To(&byte_array)) return false;
set_empty_byte_array(byte_array);
}
#define ALLOCATE_EMPTY_EXTERNAL_ARRAY(Type, type, TYPE, ctype, size) \
{ ExternalArray* obj; \
- if (!AllocateEmptyExternalArray(kExternal##Type##Array)->To(&obj)) \
+ if (!AllocateEmptyExternalArray(kExternal##Type##Array).To(&obj)) \
return false; \
set_empty_external_##type##_array(obj); \
}
@@ -2953,7 +2648,7 @@ bool Heap::CreateInitialMaps() {
#define ALLOCATE_EMPTY_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
{ FixedTypedArrayBase* obj; \
- if (!AllocateEmptyFixedTypedArray(kExternal##Type##Array)->To(&obj)) \
+ if (!AllocateEmptyFixedTypedArray(kExternal##Type##Array).To(&obj)) \
return false; \
set_empty_fixed_##type##_array(obj); \
}
@@ -2966,7 +2661,8 @@ bool Heap::CreateInitialMaps() {
}
-MaybeObject* Heap::AllocateHeapNumber(double value, PretenureFlag pretenure) {
+AllocationResult Heap::AllocateHeapNumber(double value,
+ PretenureFlag pretenure) {
// Statically ensure that it is safe to allocate heap numbers in paged
// spaces.
int size = HeapNumber::kSize;
@@ -2974,42 +2670,41 @@ MaybeObject* Heap::AllocateHeapNumber(double value, PretenureFlag pretenure) {
AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure);
- Object* result;
- { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ HeapObject* result;
+ { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
+ if (!allocation.To(&result)) return allocation;
}
- HeapObject::cast(result)->set_map_no_write_barrier(heap_number_map());
+ result->set_map_no_write_barrier(heap_number_map());
HeapNumber::cast(result)->set_value(value);
return result;
}
-MaybeObject* Heap::AllocateCell(Object* value) {
+AllocationResult Heap::AllocateCell(Object* value) {
int size = Cell::kSize;
STATIC_ASSERT(Cell::kSize <= Page::kMaxRegularHeapObjectSize);
- Object* result;
- { MaybeObject* maybe_result = AllocateRaw(size, CELL_SPACE, CELL_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ HeapObject* result;
+ { AllocationResult allocation = AllocateRaw(size, CELL_SPACE, CELL_SPACE);
+ if (!allocation.To(&result)) return allocation;
}
- HeapObject::cast(result)->set_map_no_write_barrier(cell_map());
+ result->set_map_no_write_barrier(cell_map());
Cell::cast(result)->set_value(value);
return result;
}
-MaybeObject* Heap::AllocatePropertyCell() {
+AllocationResult Heap::AllocatePropertyCell() {
int size = PropertyCell::kSize;
STATIC_ASSERT(PropertyCell::kSize <= Page::kMaxRegularHeapObjectSize);
- Object* result;
- MaybeObject* maybe_result =
+ HeapObject* result;
+ AllocationResult allocation =
AllocateRaw(size, PROPERTY_CELL_SPACE, PROPERTY_CELL_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ if (!allocation.To(&result)) return allocation;
- HeapObject::cast(result)->set_map_no_write_barrier(
- global_property_cell_map());
+ result->set_map_no_write_barrier(global_property_cell_map());
PropertyCell* cell = PropertyCell::cast(result);
cell->set_dependent_code(DependentCode::cast(empty_fixed_array()),
SKIP_WRITE_BARRIER);
@@ -3019,78 +2714,36 @@ MaybeObject* Heap::AllocatePropertyCell() {
}
-MaybeObject* Heap::AllocateBox(Object* value, PretenureFlag pretenure) {
- Box* result;
- MaybeObject* maybe_result = AllocateStruct(BOX_TYPE);
- if (!maybe_result->To(&result)) return maybe_result;
- result->set_value(value);
- return result;
-}
-
-
-MaybeObject* Heap::AllocateAllocationSite() {
- AllocationSite* site;
- MaybeObject* maybe_result = Allocate(allocation_site_map(),
- OLD_POINTER_SPACE);
- if (!maybe_result->To(&site)) return maybe_result;
- site->Initialize();
-
- // Link the site
- site->set_weak_next(allocation_sites_list());
- set_allocation_sites_list(site);
- return site;
-}
-
-
-MaybeObject* Heap::CreateOddball(const char* to_string,
- Object* to_number,
- byte kind) {
- Object* result;
- { MaybeObject* maybe_result = Allocate(oddball_map(), OLD_POINTER_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- return Oddball::cast(result)->Initialize(this, to_string, to_number, kind);
-}
-
-
-bool Heap::CreateApiObjects() {
- Object* obj;
+void Heap::CreateApiObjects() {
+ HandleScope scope(isolate());
+ Factory* factory = isolate()->factory();
+ Handle<Map> new_neander_map =
+ factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
- { MaybeObject* maybe_obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
// Don't use Smi-only elements optimizations for objects with the neander
// map. There are too many cases where element values are set directly with a
// bottleneck to trap the Smi-only -> fast elements transition, and there
// appears to be no benefit for optimize this case.
- Map* new_neander_map = Map::cast(obj);
new_neander_map->set_elements_kind(TERMINAL_FAST_ELEMENTS_KIND);
- set_neander_map(new_neander_map);
+ set_neander_map(*new_neander_map);
- { MaybeObject* maybe_obj = AllocateJSObjectFromMap(neander_map());
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- Object* elements;
- { MaybeObject* maybe_elements = AllocateFixedArray(2);
- if (!maybe_elements->ToObject(&elements)) return false;
- }
- FixedArray::cast(elements)->set(0, Smi::FromInt(0));
- JSObject::cast(obj)->set_elements(FixedArray::cast(elements));
- set_message_listeners(JSObject::cast(obj));
-
- return true;
+ Handle<JSObject> listeners = factory->NewNeanderObject();
+ Handle<FixedArray> elements = factory->NewFixedArray(2);
+ elements->set(0, Smi::FromInt(0));
+ listeners->set_elements(*elements);
+ set_message_listeners(*listeners);
}
void Heap::CreateJSEntryStub() {
- JSEntryStub stub;
- set_js_entry_code(*stub.GetCode(isolate()));
+ JSEntryStub stub(isolate());
+ set_js_entry_code(*stub.GetCode());
}
void Heap::CreateJSConstructEntryStub() {
- JSConstructEntryStub stub;
- set_js_construct_entry_code(*stub.GetCode(isolate()));
+ JSConstructEntryStub stub(isolate());
+ set_js_construct_entry_code(*stub.GetCode());
}
@@ -3124,108 +2777,86 @@ void Heap::CreateFixedStubs() {
}
-bool Heap::CreateInitialObjects() {
- Object* obj;
+void Heap::CreateInitialObjects() {
+ HandleScope scope(isolate());
+ Factory* factory = isolate()->factory();
// The -0 value must be set before NumberFromDouble works.
- { MaybeObject* maybe_obj = AllocateHeapNumber(-0.0, TENURED);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_minus_zero_value(HeapNumber::cast(obj));
+ set_minus_zero_value(*factory->NewHeapNumber(-0.0, TENURED));
ASSERT(std::signbit(minus_zero_value()->Number()) != 0);
- { MaybeObject* maybe_obj = AllocateHeapNumber(OS::nan_value(), TENURED);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_nan_value(HeapNumber::cast(obj));
-
- { MaybeObject* maybe_obj = AllocateHeapNumber(V8_INFINITY, TENURED);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_infinity_value(HeapNumber::cast(obj));
+ set_nan_value(*factory->NewHeapNumber(OS::nan_value(), TENURED));
+ set_infinity_value(*factory->NewHeapNumber(V8_INFINITY, TENURED));
// The hole has not been created yet, but we want to put something
// predictable in the gaps in the string table, so lets make that Smi zero.
set_the_hole_value(reinterpret_cast<Oddball*>(Smi::FromInt(0)));
// Allocate initial string table.
- { MaybeObject* maybe_obj =
- StringTable::Allocate(this, kInitialStringTableSize);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- // Don't use set_string_table() due to asserts.
- roots_[kStringTableRootIndex] = obj;
+ set_string_table(*StringTable::New(isolate(), kInitialStringTableSize));
// Finish initializing oddballs after creating the string table.
- { MaybeObject* maybe_obj =
- undefined_value()->Initialize(this,
- "undefined",
- nan_value(),
- Oddball::kUndefined);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
+ Oddball::Initialize(isolate(),
+ factory->undefined_value(),
+ "undefined",
+ factory->nan_value(),
+ Oddball::kUndefined);
// Initialize the null_value.
- { MaybeObject* maybe_obj = null_value()->Initialize(
- this, "null", Smi::FromInt(0), Oddball::kNull);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
-
- { MaybeObject* maybe_obj = CreateOddball("true",
- Smi::FromInt(1),
- Oddball::kTrue);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_true_value(Oddball::cast(obj));
-
- { MaybeObject* maybe_obj = CreateOddball("false",
- Smi::FromInt(0),
- Oddball::kFalse);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_false_value(Oddball::cast(obj));
-
- { MaybeObject* maybe_obj = CreateOddball("hole",
- Smi::FromInt(-1),
- Oddball::kTheHole);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_the_hole_value(Oddball::cast(obj));
-
- { MaybeObject* maybe_obj = CreateOddball("uninitialized",
- Smi::FromInt(-1),
- Oddball::kUninitialized);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_uninitialized_value(Oddball::cast(obj));
-
- { MaybeObject* maybe_obj = CreateOddball("arguments_marker",
- Smi::FromInt(-4),
- Oddball::kArgumentMarker);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_arguments_marker(Oddball::cast(obj));
-
- { MaybeObject* maybe_obj = CreateOddball("no_interceptor_result_sentinel",
- Smi::FromInt(-2),
- Oddball::kOther);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_no_interceptor_result_sentinel(obj);
-
- { MaybeObject* maybe_obj = CreateOddball("termination_exception",
- Smi::FromInt(-3),
- Oddball::kOther);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_termination_exception(obj);
+ Oddball::Initialize(isolate(),
+ factory->null_value(),
+ "null",
+ handle(Smi::FromInt(0), isolate()),
+ Oddball::kNull);
+
+ set_true_value(*factory->NewOddball(factory->boolean_map(),
+ "true",
+ handle(Smi::FromInt(1), isolate()),
+ Oddball::kTrue));
+
+ set_false_value(*factory->NewOddball(factory->boolean_map(),
+ "false",
+ handle(Smi::FromInt(0), isolate()),
+ Oddball::kFalse));
+
+ set_the_hole_value(*factory->NewOddball(factory->the_hole_map(),
+ "hole",
+ handle(Smi::FromInt(-1), isolate()),
+ Oddball::kTheHole));
+
+ set_uninitialized_value(
+ *factory->NewOddball(factory->uninitialized_map(),
+ "uninitialized",
+ handle(Smi::FromInt(-1), isolate()),
+ Oddball::kUninitialized));
+
+ set_arguments_marker(*factory->NewOddball(factory->arguments_marker_map(),
+ "arguments_marker",
+ handle(Smi::FromInt(-4), isolate()),
+ Oddball::kArgumentMarker));
+
+ set_no_interceptor_result_sentinel(
+ *factory->NewOddball(factory->no_interceptor_result_sentinel_map(),
+ "no_interceptor_result_sentinel",
+ handle(Smi::FromInt(-2), isolate()),
+ Oddball::kOther));
+
+ set_termination_exception(
+ *factory->NewOddball(factory->termination_exception_map(),
+ "termination_exception",
+ handle(Smi::FromInt(-3), isolate()),
+ Oddball::kOther));
+
+ set_exception(
+ *factory->NewOddball(factory->exception_map(),
+ "exception",
+ handle(Smi::FromInt(-5), isolate()),
+ Oddball::kException));
for (unsigned i = 0; i < ARRAY_SIZE(constant_string_table); i++) {
- { MaybeObject* maybe_obj =
- InternalizeUtf8String(constant_string_table[i].contents);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- roots_[constant_string_table[i].index] = String::cast(obj);
+ Handle<String> str =
+ factory->InternalizeUtf8String(constant_string_table[i].contents);
+ roots_[constant_string_table[i].index] = *str;
}
// Allocate the hidden string which is used to identify the hidden properties
@@ -3234,31 +2865,19 @@ bool Heap::CreateInitialObjects() {
// loop above because it needs to be allocated manually with the special
// hash code in place. The hash code for the hidden_string is zero to ensure
// that it will always be at the first entry in property descriptors.
- { MaybeObject* maybe_obj = AllocateOneByteInternalizedString(
+ hidden_string_ = *factory->NewOneByteInternalizedString(
OneByteVector("", 0), String::kEmptyStringHash);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- hidden_string_ = String::cast(obj);
- // Allocate the code_stubs dictionary. The initial size is set to avoid
+ // Create the code_stubs dictionary. The initial size is set to avoid
// expanding the dictionary during bootstrapping.
- { MaybeObject* maybe_obj = UnseededNumberDictionary::Allocate(this, 128);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_code_stubs(UnseededNumberDictionary::cast(obj));
-
+ set_code_stubs(*UnseededNumberDictionary::New(isolate(), 128));
- // Allocate the non_monomorphic_cache used in stub-cache.cc. The initial size
+ // Create the non_monomorphic_cache used in stub-cache.cc. The initial size
// is set to avoid expanding the dictionary during bootstrapping.
- { MaybeObject* maybe_obj = UnseededNumberDictionary::Allocate(this, 64);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_non_monomorphic_cache(UnseededNumberDictionary::cast(obj));
+ set_non_monomorphic_cache(*UnseededNumberDictionary::New(isolate(), 64));
- { MaybeObject* maybe_obj = AllocatePolymorphicCodeCache();
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_polymorphic_code_cache(PolymorphicCodeCache::cast(obj));
+ set_polymorphic_code_cache(PolymorphicCodeCache::cast(
+ *factory->NewStruct(POLYMORPHIC_CODE_CACHE_TYPE)));
set_instanceof_cache_function(Smi::FromInt(0));
set_instanceof_cache_map(Smi::FromInt(0));
@@ -3267,127 +2886,60 @@ bool Heap::CreateInitialObjects() {
CreateFixedStubs();
// Allocate the dictionary of intrinsic function names.
- { MaybeObject* maybe_obj =
- NameDictionary::Allocate(this, Runtime::kNumFunctions);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- { MaybeObject* maybe_obj = Runtime::InitializeIntrinsicFunctionNames(this,
- obj);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_intrinsic_function_names(NameDictionary::cast(obj));
+ Handle<NameDictionary> intrinsic_names =
+ NameDictionary::New(isolate(), Runtime::kNumFunctions);
+ Runtime::InitializeIntrinsicFunctionNames(isolate(), intrinsic_names);
+ set_intrinsic_function_names(*intrinsic_names);
- { MaybeObject* maybe_obj = AllocateInitialNumberStringCache();
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_number_string_cache(FixedArray::cast(obj));
+ set_number_string_cache(*factory->NewFixedArray(
+ kInitialNumberStringCacheSize * 2, TENURED));
// Allocate cache for single character one byte strings.
- { MaybeObject* maybe_obj =
- AllocateFixedArray(String::kMaxOneByteCharCode + 1, TENURED);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_single_character_string_cache(FixedArray::cast(obj));
+ set_single_character_string_cache(*factory->NewFixedArray(
+ String::kMaxOneByteCharCode + 1, TENURED));
- // Allocate cache for string split.
- { MaybeObject* maybe_obj = AllocateFixedArray(
- RegExpResultsCache::kRegExpResultsCacheSize, TENURED);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_string_split_cache(FixedArray::cast(obj));
-
- { MaybeObject* maybe_obj = AllocateFixedArray(
- RegExpResultsCache::kRegExpResultsCacheSize, TENURED);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_regexp_multiple_cache(FixedArray::cast(obj));
+ // Allocate cache for string split and regexp-multiple.
+ set_string_split_cache(*factory->NewFixedArray(
+ RegExpResultsCache::kRegExpResultsCacheSize, TENURED));
+ set_regexp_multiple_cache(*factory->NewFixedArray(
+ RegExpResultsCache::kRegExpResultsCacheSize, TENURED));
// Allocate cache for external strings pointing to native source code.
- { MaybeObject* maybe_obj = AllocateFixedArray(Natives::GetBuiltinsCount());
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_natives_source_cache(FixedArray::cast(obj));
+ set_natives_source_cache(*factory->NewFixedArray(
+ Natives::GetBuiltinsCount()));
- { MaybeObject* maybe_obj = AllocateCell(undefined_value());
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_undefined_cell(Cell::cast(obj));
+ set_undefined_cell(*factory->NewCell(factory->undefined_value()));
// The symbol registry is initialized lazily.
set_symbol_registry(undefined_value());
// Allocate object to hold object observation state.
- { MaybeObject* maybe_obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- { MaybeObject* maybe_obj = AllocateJSObjectFromMap(Map::cast(obj));
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_observation_state(JSObject::cast(obj));
+ set_observation_state(*factory->NewJSObjectFromMap(
+ factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize)));
// Allocate object to hold object microtask state.
- { MaybeObject* maybe_obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- { MaybeObject* maybe_obj = AllocateJSObjectFromMap(Map::cast(obj));
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_microtask_state(JSObject::cast(obj));
-
- { MaybeObject* maybe_obj = AllocateSymbol();
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- Symbol::cast(obj)->set_is_private(true);
- set_frozen_symbol(Symbol::cast(obj));
-
- { MaybeObject* maybe_obj = AllocateSymbol();
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- Symbol::cast(obj)->set_is_private(true);
- set_nonexistent_symbol(Symbol::cast(obj));
-
- { MaybeObject* maybe_obj = AllocateSymbol();
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- Symbol::cast(obj)->set_is_private(true);
- set_elements_transition_symbol(Symbol::cast(obj));
+ set_microtask_state(*factory->NewJSObjectFromMap(
+ factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize)));
- { MaybeObject* maybe_obj = AllocateSymbol();
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- Symbol::cast(obj)->set_is_private(true);
- set_uninitialized_symbol(Symbol::cast(obj));
+ set_frozen_symbol(*factory->NewPrivateSymbol());
+ set_nonexistent_symbol(*factory->NewPrivateSymbol());
+ set_elements_transition_symbol(*factory->NewPrivateSymbol());
+ set_uninitialized_symbol(*factory->NewPrivateSymbol());
+ set_megamorphic_symbol(*factory->NewPrivateSymbol());
+ set_observed_symbol(*factory->NewPrivateSymbol());
- { MaybeObject* maybe_obj = AllocateSymbol();
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- Symbol::cast(obj)->set_is_private(true);
- set_megamorphic_symbol(Symbol::cast(obj));
+ Handle<SeededNumberDictionary> slow_element_dictionary =
+ SeededNumberDictionary::New(isolate(), 0, TENURED);
+ slow_element_dictionary->set_requires_slow_elements();
+ set_empty_slow_element_dictionary(*slow_element_dictionary);
- { MaybeObject* maybe_obj = SeededNumberDictionary::Allocate(this, 0, TENURED);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- SeededNumberDictionary::cast(obj)->set_requires_slow_elements();
- set_empty_slow_element_dictionary(SeededNumberDictionary::cast(obj));
-
- { MaybeObject* maybe_obj = AllocateSymbol();
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- Symbol::cast(obj)->set_is_private(true);
- set_observed_symbol(Symbol::cast(obj));
-
- { MaybeObject* maybe_obj = AllocateFixedArray(0, TENURED);
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_materialized_objects(FixedArray::cast(obj));
+ set_materialized_objects(*factory->NewFixedArray(0, TENURED));
// Handling of script id generation is in Factory::NewScript.
set_last_script_id(Smi::FromInt(v8::UnboundScript::kNoScriptId));
- { MaybeObject* maybe_obj = AllocateAllocationSitesScratchpad();
- if (!maybe_obj->ToObject(&obj)) return false;
- }
- set_allocation_sites_scratchpad(FixedArray::cast(obj));
+ set_allocation_sites_scratchpad(*factory->NewFixedArray(
+ kAllocationSiteScratchpadSize, TENURED));
InitializeAllocationSitesScratchpad();
// Initialize keyed lookup cache.
@@ -3401,8 +2953,6 @@ bool Heap::CreateInitialObjects() {
// Initialize compilation cache.
isolate_->compilation_cache()->Clear();
-
- return true;
}
@@ -3474,60 +3024,58 @@ Object* RegExpResultsCache::Lookup(Heap* heap,
}
-void RegExpResultsCache::Enter(Heap* heap,
- String* key_string,
- Object* key_pattern,
- FixedArray* value_array,
+void RegExpResultsCache::Enter(Isolate* isolate,
+ Handle<String> key_string,
+ Handle<Object> key_pattern,
+ Handle<FixedArray> value_array,
ResultsCacheType type) {
- FixedArray* cache;
+ Factory* factory = isolate->factory();
+ Handle<FixedArray> cache;
if (!key_string->IsInternalizedString()) return;
if (type == STRING_SPLIT_SUBSTRINGS) {
ASSERT(key_pattern->IsString());
if (!key_pattern->IsInternalizedString()) return;
- cache = heap->string_split_cache();
+ cache = factory->string_split_cache();
} else {
ASSERT(type == REGEXP_MULTIPLE_INDICES);
ASSERT(key_pattern->IsFixedArray());
- cache = heap->regexp_multiple_cache();
+ cache = factory->regexp_multiple_cache();
}
uint32_t hash = key_string->Hash();
uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) &
~(kArrayEntriesPerCacheEntry - 1));
if (cache->get(index + kStringOffset) == Smi::FromInt(0)) {
- cache->set(index + kStringOffset, key_string);
- cache->set(index + kPatternOffset, key_pattern);
- cache->set(index + kArrayOffset, value_array);
+ cache->set(index + kStringOffset, *key_string);
+ cache->set(index + kPatternOffset, *key_pattern);
+ cache->set(index + kArrayOffset, *value_array);
} else {
uint32_t index2 =
((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1));
if (cache->get(index2 + kStringOffset) == Smi::FromInt(0)) {
- cache->set(index2 + kStringOffset, key_string);
- cache->set(index2 + kPatternOffset, key_pattern);
- cache->set(index2 + kArrayOffset, value_array);
+ cache->set(index2 + kStringOffset, *key_string);
+ cache->set(index2 + kPatternOffset, *key_pattern);
+ cache->set(index2 + kArrayOffset, *value_array);
} else {
cache->set(index2 + kStringOffset, Smi::FromInt(0));
cache->set(index2 + kPatternOffset, Smi::FromInt(0));
cache->set(index2 + kArrayOffset, Smi::FromInt(0));
- cache->set(index + kStringOffset, key_string);
- cache->set(index + kPatternOffset, key_pattern);
- cache->set(index + kArrayOffset, value_array);
+ cache->set(index + kStringOffset, *key_string);
+ cache->set(index + kPatternOffset, *key_pattern);
+ cache->set(index + kArrayOffset, *value_array);
}
}
// If the array is a reasonably short list of substrings, convert it into a
// list of internalized strings.
if (type == STRING_SPLIT_SUBSTRINGS && value_array->length() < 100) {
for (int i = 0; i < value_array->length(); i++) {
- String* str = String::cast(value_array->get(i));
- Object* internalized_str;
- MaybeObject* maybe_string = heap->InternalizeString(str);
- if (maybe_string->ToObject(&internalized_str)) {
- value_array->set(i, internalized_str);
- }
+ Handle<String> str(String::cast(value_array->get(i)), isolate);
+ Handle<String> internalized_str = factory->InternalizeString(str);
+ value_array->set(i, *internalized_str);
}
}
// Convert backing store to a copy-on-write array.
- value_array->set_map_no_write_barrier(heap->fixed_cow_array_map());
+ value_array->set_map_no_write_barrier(*factory->fixed_cow_array_map());
}
@@ -3538,13 +3086,6 @@ void RegExpResultsCache::Clear(FixedArray* cache) {
}
-MaybeObject* Heap::AllocateInitialNumberStringCache() {
- MaybeObject* maybe_obj =
- AllocateFixedArray(kInitialNumberStringCacheSize * 2, TENURED);
- return maybe_obj;
-}
-
-
int Heap::FullSizeNumberStringCacheLength() {
// Compute the size of the number string cache based on the max newspace size.
// The number string cache has a minimum size based on twice the initial cache
@@ -3558,24 +3099,6 @@ int Heap::FullSizeNumberStringCacheLength() {
}
-void Heap::AllocateFullSizeNumberStringCache() {
- // The idea is to have a small number string cache in the snapshot to keep
- // boot-time memory usage down. If we expand the number string cache already
- // while creating the snapshot then that didn't work out.
- ASSERT(!Serializer::enabled() || FLAG_extra_code != NULL);
- MaybeObject* maybe_obj =
- AllocateFixedArray(FullSizeNumberStringCacheLength(), TENURED);
- Object* new_cache;
- if (maybe_obj->ToObject(&new_cache)) {
- // We don't bother to repopulate the cache with entries from the old cache.
- // It will be repopulated soon enough with new strings.
- set_number_string_cache(FixedArray::cast(new_cache));
- }
- // If allocation fails then we just return without doing anything. It is only
- // a cache, so best effort is OK here.
-}
-
-
void Heap::FlushNumberStringCache() {
// Flush the number to string cache.
int len = number_string_cache()->length();
@@ -3585,107 +3108,6 @@ void Heap::FlushNumberStringCache() {
}
-static inline int double_get_hash(double d) {
- DoubleRepresentation rep(d);
- return static_cast<int>(rep.bits) ^ static_cast<int>(rep.bits >> 32);
-}
-
-
-static inline int smi_get_hash(Smi* smi) {
- return smi->value();
-}
-
-
-Object* Heap::GetNumberStringCache(Object* number) {
- int hash;
- int mask = (number_string_cache()->length() >> 1) - 1;
- if (number->IsSmi()) {
- hash = smi_get_hash(Smi::cast(number)) & mask;
- } else {
- hash = double_get_hash(number->Number()) & mask;
- }
- Object* key = number_string_cache()->get(hash * 2);
- if (key == number) {
- return String::cast(number_string_cache()->get(hash * 2 + 1));
- } else if (key->IsHeapNumber() &&
- number->IsHeapNumber() &&
- key->Number() == number->Number()) {
- return String::cast(number_string_cache()->get(hash * 2 + 1));
- }
- return undefined_value();
-}
-
-
-void Heap::SetNumberStringCache(Object* number, String* string) {
- int hash;
- int mask = (number_string_cache()->length() >> 1) - 1;
- if (number->IsSmi()) {
- hash = smi_get_hash(Smi::cast(number)) & mask;
- } else {
- hash = double_get_hash(number->Number()) & mask;
- }
- if (number_string_cache()->get(hash * 2) != undefined_value() &&
- number_string_cache()->length() != FullSizeNumberStringCacheLength()) {
- // The first time we have a hash collision, we move to the full sized
- // number string cache.
- AllocateFullSizeNumberStringCache();
- return;
- }
- number_string_cache()->set(hash * 2, number);
- number_string_cache()->set(hash * 2 + 1, string);
-}
-
-
-MaybeObject* Heap::NumberToString(Object* number,
- bool check_number_string_cache) {
- isolate_->counters()->number_to_string_runtime()->Increment();
- if (check_number_string_cache) {
- Object* cached = GetNumberStringCache(number);
- if (cached != undefined_value()) {
- return cached;
- }
- }
-
- char arr[100];
- Vector<char> buffer(arr, ARRAY_SIZE(arr));
- const char* str;
- if (number->IsSmi()) {
- int num = Smi::cast(number)->value();
- str = IntToCString(num, buffer);
- } else {
- double num = HeapNumber::cast(number)->value();
- str = DoubleToCString(num, buffer);
- }
-
- Object* js_string;
-
- // We tenure the allocated string since it is referenced from the
- // number-string cache which lives in the old space.
- MaybeObject* maybe_js_string =
- AllocateStringFromOneByte(CStrVector(str), TENURED);
- if (maybe_js_string->ToObject(&js_string)) {
- SetNumberStringCache(number, String::cast(js_string));
- }
- return maybe_js_string;
-}
-
-
-MaybeObject* Heap::Uint32ToString(uint32_t value,
- bool check_number_string_cache) {
- Object* number;
- MaybeObject* maybe = NumberFromUint32(value);
- if (!maybe->To<Object>(&number)) return maybe;
- return NumberToString(number, check_number_string_cache);
-}
-
-
-MaybeObject* Heap::AllocateAllocationSitesScratchpad() {
- MaybeObject* maybe_obj =
- AllocateFixedArray(kAllocationSiteScratchpadSize, TENURED);
- return maybe_obj;
-}
-
-
void Heap::FlushAllocationSitesScratchpad() {
for (int i = 0; i < allocation_sites_scratchpad_length_; i++) {
allocation_sites_scratchpad()->set_undefined(i);
@@ -3816,188 +3238,32 @@ FixedTypedArrayBase* Heap::EmptyFixedTypedArrayForMap(Map* map) {
}
-MaybeObject* Heap::NumberFromDouble(double value, PretenureFlag pretenure) {
- // We need to distinguish the minus zero value and this cannot be
- // done after conversion to int. Doing this by comparing bit
- // patterns is faster than using fpclassify() et al.
- if (IsMinusZero(value)) {
- return AllocateHeapNumber(-0.0, pretenure);
- }
-
- int int_value = FastD2I(value);
- if (value == int_value && Smi::IsValid(int_value)) {
- return Smi::FromInt(int_value);
- }
-
- // Materialize the value in the heap.
- return AllocateHeapNumber(value, pretenure);
-}
-
-
-MaybeObject* Heap::AllocateForeign(Address address, PretenureFlag pretenure) {
+AllocationResult Heap::AllocateForeign(Address address,
+ PretenureFlag pretenure) {
// Statically ensure that it is safe to allocate foreigns in paged spaces.
STATIC_ASSERT(Foreign::kSize <= Page::kMaxRegularHeapObjectSize);
AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
Foreign* result;
- MaybeObject* maybe_result = Allocate(foreign_map(), space);
- if (!maybe_result->To(&result)) return maybe_result;
+ AllocationResult allocation = Allocate(foreign_map(), space);
+ if (!allocation.To(&result)) return allocation;
result->set_foreign_address(address);
return result;
}
-MaybeObject* Heap::AllocateSharedFunctionInfo(Object* name) {
- SharedFunctionInfo* share;
- MaybeObject* maybe = Allocate(shared_function_info_map(), OLD_POINTER_SPACE);
- if (!maybe->To<SharedFunctionInfo>(&share)) return maybe;
-
- // Set pointer fields.
- share->set_name(name);
- Code* illegal = isolate_->builtins()->builtin(Builtins::kIllegal);
- share->set_code(illegal);
- share->set_optimized_code_map(Smi::FromInt(0));
- share->set_scope_info(ScopeInfo::Empty(isolate_));
- Code* construct_stub =
- isolate_->builtins()->builtin(Builtins::kJSConstructStubGeneric);
- share->set_construct_stub(construct_stub);
- share->set_instance_class_name(Object_string());
- share->set_function_data(undefined_value(), SKIP_WRITE_BARRIER);
- share->set_script(undefined_value(), SKIP_WRITE_BARRIER);
- share->set_debug_info(undefined_value(), SKIP_WRITE_BARRIER);
- share->set_inferred_name(empty_string(), SKIP_WRITE_BARRIER);
- share->set_initial_map(undefined_value(), SKIP_WRITE_BARRIER);
- share->set_ast_node_count(0);
- share->set_counters(0);
-
- // Set integer fields (smi or int, depending on the architecture).
- share->set_length(0);
- share->set_formal_parameter_count(0);
- share->set_expected_nof_properties(0);
- share->set_num_literals(0);
- share->set_start_position_and_type(0);
- share->set_end_position(0);
- share->set_function_token_position(0);
- // All compiler hints default to false or 0.
- share->set_compiler_hints(0);
- share->set_opt_count_and_bailout_reason(0);
-
- return share;
-}
-
-
-MaybeObject* Heap::AllocateJSMessageObject(String* type,
- JSArray* arguments,
- int start_position,
- int end_position,
- Object* script,
- Object* stack_frames) {
- Object* result;
- { MaybeObject* maybe_result = Allocate(message_object_map(), NEW_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- JSMessageObject* message = JSMessageObject::cast(result);
- message->set_properties(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER);
- message->initialize_elements();
- message->set_elements(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER);
- message->set_type(type);
- message->set_arguments(arguments);
- message->set_start_position(start_position);
- message->set_end_position(end_position);
- message->set_script(script);
- message->set_stack_frames(stack_frames);
- return result;
-}
-
-
-MaybeObject* Heap::AllocateExternalStringFromAscii(
- const ExternalAsciiString::Resource* resource) {
- size_t length = resource->length();
- if (length > static_cast<size_t>(String::kMaxLength)) {
- return isolate()->ThrowInvalidStringLength();
- }
-
- Map* map = external_ascii_string_map();
- Object* result;
- { MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
-
- ExternalAsciiString* external_string = ExternalAsciiString::cast(result);
- external_string->set_length(static_cast<int>(length));
- external_string->set_hash_field(String::kEmptyHashField);
- external_string->set_resource(resource);
-
- return result;
-}
-
-
-MaybeObject* Heap::AllocateExternalStringFromTwoByte(
- const ExternalTwoByteString::Resource* resource) {
- size_t length = resource->length();
- if (length > static_cast<size_t>(String::kMaxLength)) {
- return isolate()->ThrowInvalidStringLength();
- }
-
- // For small strings we check whether the resource contains only
- // one byte characters. If yes, we use a different string map.
- static const size_t kOneByteCheckLengthLimit = 32;
- bool is_one_byte = length <= kOneByteCheckLengthLimit &&
- String::IsOneByte(resource->data(), static_cast<int>(length));
- Map* map = is_one_byte ?
- external_string_with_one_byte_data_map() : external_string_map();
- Object* result;
- { MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
-
- ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result);
- external_string->set_length(static_cast<int>(length));
- external_string->set_hash_field(String::kEmptyHashField);
- external_string->set_resource(resource);
-
- return result;
-}
-
-
-MaybeObject* Heap::LookupSingleCharacterStringFromCode(uint16_t code) {
- if (code <= String::kMaxOneByteCharCode) {
- Object* value = single_character_string_cache()->get(code);
- if (value != undefined_value()) return value;
-
- uint8_t buffer[1];
- buffer[0] = static_cast<uint8_t>(code);
- Object* result;
- OneByteStringKey key(Vector<const uint8_t>(buffer, 1), HashSeed());
- MaybeObject* maybe_result = InternalizeStringWithKey(&key);
-
- if (!maybe_result->ToObject(&result)) return maybe_result;
- single_character_string_cache()->set(code, result);
- return result;
- }
-
- SeqTwoByteString* result;
- { MaybeObject* maybe_result = AllocateRawTwoByteString(1);
- if (!maybe_result->To<SeqTwoByteString>(&result)) return maybe_result;
- }
- result->SeqTwoByteStringSet(0, code);
- return result;
-}
-
-
-MaybeObject* Heap::AllocateByteArray(int length, PretenureFlag pretenure) {
+AllocationResult Heap::AllocateByteArray(int length, PretenureFlag pretenure) {
if (length < 0 || length > ByteArray::kMaxLength) {
v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
}
int size = ByteArray::SizeFor(length);
AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure);
- Object* result;
- { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ HeapObject* result;
+ { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
+ if (!allocation.To(&result)) return allocation;
}
- reinterpret_cast<ByteArray*>(result)->set_map_no_write_barrier(
- byte_array_map());
- reinterpret_cast<ByteArray*>(result)->set_length(length);
+ result->set_map_no_write_barrier(byte_array_map());
+ ByteArray::cast(result)->set_length(length);
return result;
}
@@ -4023,11 +3289,18 @@ bool Heap::CanMoveObjectStart(HeapObject* object) {
if (lo_space()->Contains(object)) return false;
- // We cannot move the object start if the given old space page is
- // concurrently swept.
+ Page* page = Page::FromAddress(address);
+ // We can move the object start if:
+ // (1) the object is not in old pointer or old data space,
+ // (2) the page of the object was already swept,
+ // (3) the page was already concurrently swept. This case is an optimization
+ // for concurrent sweeping. The WasSwept predicate for concurrently swept
+ // pages is set after sweeping all pages.
return (!is_in_old_pointer_space && !is_in_old_data_space) ||
- Page::FromAddress(address)->parallel_sweeping() <=
- MemoryChunk::PARALLEL_SWEEPING_FINALIZE;
+ page->WasSwept() ||
+ (mark_compact_collector()->AreSweeperThreadsActivated() &&
+ page->parallel_sweeping() <=
+ MemoryChunk::PARALLEL_SWEEPING_FINALIZE);
}
@@ -4043,23 +3316,21 @@ void Heap::AdjustLiveBytes(Address address, int by, InvocationMode mode) {
}
-MaybeObject* Heap::AllocateExternalArray(int length,
+AllocationResult Heap::AllocateExternalArray(int length,
ExternalArrayType array_type,
void* external_pointer,
PretenureFlag pretenure) {
int size = ExternalArray::kAlignedSize;
AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure);
- Object* result;
- { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ HeapObject* result;
+ { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
+ if (!allocation.To(&result)) return allocation;
}
- reinterpret_cast<ExternalArray*>(result)->set_map_no_write_barrier(
+ result->set_map_no_write_barrier(
MapForExternalArrayType(array_type));
- reinterpret_cast<ExternalArray*>(result)->set_length(length);
- reinterpret_cast<ExternalArray*>(result)->set_external_pointer(
- external_pointer);
-
+ ExternalArray::cast(result)->set_length(length);
+ ExternalArray::cast(result)->set_external_pointer(external_pointer);
return result;
}
@@ -4084,9 +3355,9 @@ static void ForFixedTypedArray(ExternalArrayType array_type,
}
-MaybeObject* Heap::AllocateFixedTypedArray(int length,
- ExternalArrayType array_type,
- PretenureFlag pretenure) {
+AllocationResult Heap::AllocateFixedTypedArray(int length,
+ ExternalArrayType array_type,
+ PretenureFlag pretenure) {
int element_size;
ElementsKind elements_kind;
ForFixedTypedArray(array_type, &element_size, &elements_kind);
@@ -4100,132 +3371,65 @@ MaybeObject* Heap::AllocateFixedTypedArray(int length,
AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure);
HeapObject* object;
- MaybeObject* maybe_object = AllocateRaw(size, space, OLD_DATA_SPACE);
- if (!maybe_object->To(&object)) return maybe_object;
+ AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
+ if (!allocation.To(&object)) return allocation;
if (array_type == kExternalFloat64Array) {
object = EnsureDoubleAligned(this, object, size);
}
- FixedTypedArrayBase* elements =
- reinterpret_cast<FixedTypedArrayBase*>(object);
- elements->set_map(MapForFixedTypedArray(array_type));
+ object->set_map(MapForFixedTypedArray(array_type));
+ FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(object);
elements->set_length(length);
memset(elements->DataPtr(), 0, elements->DataSize());
return elements;
}
-MaybeObject* Heap::CreateCode(const CodeDesc& desc,
- Code::Flags flags,
- Handle<Object> self_reference,
- bool immovable,
- bool crankshafted,
- int prologue_offset) {
- // Allocate ByteArray and ConstantPoolArray before the Code object, so that we
- // do not risk leaving uninitialized Code object (and breaking the heap).
- ByteArray* reloc_info;
- MaybeObject* maybe_reloc_info = AllocateByteArray(desc.reloc_size, TENURED);
- if (!maybe_reloc_info->To(&reloc_info)) return maybe_reloc_info;
-
- ConstantPoolArray* constant_pool;
- if (FLAG_enable_ool_constant_pool) {
- MaybeObject* maybe_constant_pool = desc.origin->AllocateConstantPool(this);
- if (!maybe_constant_pool->To(&constant_pool)) return maybe_constant_pool;
- } else {
- constant_pool = empty_constant_pool_array();
- }
-
- // Compute size.
- int body_size = RoundUp(desc.instr_size, kObjectAlignment);
- int obj_size = Code::SizeFor(body_size);
- ASSERT(IsAligned(static_cast<intptr_t>(obj_size), kCodeAlignment));
- MaybeObject* maybe_result;
+AllocationResult Heap::AllocateCode(int object_size,
+ bool immovable) {
+ ASSERT(IsAligned(static_cast<intptr_t>(object_size), kCodeAlignment));
+ AllocationResult allocation;
// Large code objects and code objects which should stay at a fixed address
// are allocated in large object space.
HeapObject* result;
- bool force_lo_space = obj_size > code_space()->AreaSize();
+ bool force_lo_space = object_size > code_space()->AreaSize();
if (force_lo_space) {
- maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE);
+ allocation = lo_space_->AllocateRaw(object_size, EXECUTABLE);
} else {
- maybe_result = AllocateRaw(obj_size, CODE_SPACE, CODE_SPACE);
+ allocation = AllocateRaw(object_size, CODE_SPACE, CODE_SPACE);
}
- if (!maybe_result->To<HeapObject>(&result)) return maybe_result;
+ if (!allocation.To(&result)) return allocation;
if (immovable && !force_lo_space &&
- // Objects on the first page of each space are never moved.
- !code_space_->FirstPage()->Contains(result->address())) {
+ // Objects on the first page of each space are never moved.
+ !code_space_->FirstPage()->Contains(result->address())) {
// Discard the first code allocation, which was on a page where it could be
// moved.
- CreateFillerObjectAt(result->address(), obj_size);
- maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE);
- if (!maybe_result->To<HeapObject>(&result)) return maybe_result;
+ CreateFillerObjectAt(result->address(), object_size);
+ allocation = lo_space_->AllocateRaw(object_size, EXECUTABLE);
+ if (!allocation.To(&result)) return allocation;
}
- // Initialize the object
result->set_map_no_write_barrier(code_map());
Code* code = Code::cast(result);
ASSERT(!isolate_->code_range()->exists() ||
isolate_->code_range()->contains(code->address()));
- code->set_instruction_size(desc.instr_size);
- code->set_relocation_info(reloc_info);
- code->set_flags(flags);
- code->set_raw_kind_specific_flags1(0);
- code->set_raw_kind_specific_flags2(0);
- code->set_is_crankshafted(crankshafted);
- code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER);
- code->set_raw_type_feedback_info(undefined_value());
- code->set_next_code_link(undefined_value());
- code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER);
code->set_gc_metadata(Smi::FromInt(0));
code->set_ic_age(global_ic_age_);
- code->set_prologue_offset(prologue_offset);
- if (code->kind() == Code::OPTIMIZED_FUNCTION) {
- code->set_marked_for_deoptimization(false);
- }
-
- if (FLAG_enable_ool_constant_pool) {
- desc.origin->PopulateConstantPool(constant_pool);
- }
- code->set_constant_pool(constant_pool);
-
-#ifdef ENABLE_DEBUGGER_SUPPORT
- if (code->kind() == Code::FUNCTION) {
- code->set_has_debug_break_slots(
- isolate_->debugger()->IsDebuggerActive());
- }
-#endif
-
- // Allow self references to created code object by patching the handle to
- // point to the newly allocated Code object.
- if (!self_reference.is_null()) {
- *(self_reference.location()) = code;
- }
- // Migrate generated code.
- // The generated code can contain Object** values (typically from handles)
- // that are dereferenced during the copy to point directly to the actual heap
- // objects. These pointers can include references to the code object itself,
- // through the self_reference parameter.
- code->CopyFrom(desc);
-
-#ifdef VERIFY_HEAP
- if (FLAG_verify_heap) {
- code->Verify();
- }
-#endif
return code;
}
-MaybeObject* Heap::CopyCode(Code* code) {
- MaybeObject* maybe_result;
- Object* new_constant_pool;
+AllocationResult Heap::CopyCode(Code* code) {
+ AllocationResult allocation;
+ HeapObject* new_constant_pool;
if (FLAG_enable_ool_constant_pool &&
code->constant_pool() != empty_constant_pool_array()) {
// Copy the constant pool, since edits to the copied code may modify
// the constant pool.
- maybe_result = CopyConstantPoolArray(code->constant_pool());
- if (!maybe_result->ToObject(&new_constant_pool)) return maybe_result;
+ allocation = CopyConstantPoolArray(code->constant_pool());
+ if (!allocation.To(&new_constant_pool)) return allocation;
} else {
new_constant_pool = empty_constant_pool_array();
}
@@ -4233,17 +3437,17 @@ MaybeObject* Heap::CopyCode(Code* code) {
// Allocate an object the same size as the code object.
int obj_size = code->Size();
if (obj_size > code_space()->AreaSize()) {
- maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE);
+ allocation = lo_space_->AllocateRaw(obj_size, EXECUTABLE);
} else {
- maybe_result = AllocateRaw(obj_size, CODE_SPACE, CODE_SPACE);
+ allocation = AllocateRaw(obj_size, CODE_SPACE, CODE_SPACE);
}
- Object* result;
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ HeapObject* result;
+ if (!allocation.To(&result)) return allocation;
// Copy code object.
Address old_addr = code->address();
- Address new_addr = reinterpret_cast<HeapObject*>(result)->address();
+ Address new_addr = result->address();
CopyBlock(new_addr, old_addr, obj_size);
Code* new_code = Code::cast(result);
@@ -4258,25 +3462,22 @@ MaybeObject* Heap::CopyCode(Code* code) {
}
-MaybeObject* Heap::CopyCode(Code* code, Vector<byte> reloc_info) {
+AllocationResult Heap::CopyCode(Code* code, Vector<byte> reloc_info) {
// Allocate ByteArray and ConstantPoolArray before the Code object, so that we
// do not risk leaving uninitialized Code object (and breaking the heap).
- Object* reloc_info_array;
- { MaybeObject* maybe_reloc_info_array =
+ ByteArray* reloc_info_array;
+ { AllocationResult allocation =
AllocateByteArray(reloc_info.length(), TENURED);
- if (!maybe_reloc_info_array->ToObject(&reloc_info_array)) {
- return maybe_reloc_info_array;
- }
+ if (!allocation.To(&reloc_info_array)) return allocation;
}
- Object* new_constant_pool;
+ HeapObject* new_constant_pool;
if (FLAG_enable_ool_constant_pool &&
code->constant_pool() != empty_constant_pool_array()) {
// Copy the constant pool, since edits to the copied code may modify
// the constant pool.
- MaybeObject* maybe_constant_pool =
+ AllocationResult allocation =
CopyConstantPoolArray(code->constant_pool());
- if (!maybe_constant_pool->ToObject(&new_constant_pool))
- return maybe_constant_pool;
+ if (!allocation.To(&new_constant_pool)) return allocation;
} else {
new_constant_pool = empty_constant_pool_array();
}
@@ -4290,24 +3491,24 @@ MaybeObject* Heap::CopyCode(Code* code, Vector<byte> reloc_info) {
size_t relocation_offset =
static_cast<size_t>(code->instruction_end() - old_addr);
- MaybeObject* maybe_result;
+ AllocationResult allocation;
if (new_obj_size > code_space()->AreaSize()) {
- maybe_result = lo_space_->AllocateRaw(new_obj_size, EXECUTABLE);
+ allocation = lo_space_->AllocateRaw(new_obj_size, EXECUTABLE);
} else {
- maybe_result = AllocateRaw(new_obj_size, CODE_SPACE, CODE_SPACE);
+ allocation = AllocateRaw(new_obj_size, CODE_SPACE, CODE_SPACE);
}
- Object* result;
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ HeapObject* result;
+ if (!allocation.To(&result)) return allocation;
// Copy code object.
- Address new_addr = reinterpret_cast<HeapObject*>(result)->address();
+ Address new_addr = result->address();
// Copy header and instructions.
CopyBytes(new_addr, old_addr, relocation_offset);
Code* new_code = Code::cast(result);
- new_code->set_relocation_info(ByteArray::cast(reloc_info_array));
+ new_code->set_relocation_info(reloc_info_array);
// Update constant pool.
new_code->set_constant_pool(new_constant_pool);
@@ -4323,9 +3524,7 @@ MaybeObject* Heap::CopyCode(Code* code, Vector<byte> reloc_info) {
new_code->Relocate(new_addr - old_addr);
#ifdef VERIFY_HEAP
- if (FLAG_verify_heap) {
- code->Verify();
- }
+ if (FLAG_verify_heap) code->ObjectVerify();
#endif
return new_code;
}
@@ -4342,7 +3541,7 @@ void Heap::InitializeAllocationMemento(AllocationMemento* memento,
}
-MaybeObject* Heap::Allocate(Map* map, AllocationSpace space,
+AllocationResult Heap::Allocate(Map* map, AllocationSpace space,
AllocationSite* allocation_site) {
ASSERT(gc_state_ == NOT_IN_GC);
ASSERT(map->instance_type() != MAP_TYPE);
@@ -4354,11 +3553,11 @@ MaybeObject* Heap::Allocate(Map* map, AllocationSpace space,
if (allocation_site != NULL) {
size += AllocationMemento::kSize;
}
- Object* result;
- MaybeObject* maybe_result = AllocateRaw(size, space, retry_space);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ HeapObject* result;
+ AllocationResult allocation = AllocateRaw(size, space, retry_space);
+ if (!allocation.To(&result)) return allocation;
// No need for write barrier since object is white and map is in old space.
- HeapObject::cast(result)->set_map_no_write_barrier(map);
+ result->set_map_no_write_barrier(map);
if (allocation_site != NULL) {
AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>(
reinterpret_cast<Address>(result) + map->instance_size());
@@ -4368,37 +3567,7 @@ MaybeObject* Heap::Allocate(Map* map, AllocationSpace space,
}
-void Heap::InitializeFunction(JSFunction* function,
- SharedFunctionInfo* shared,
- Object* prototype) {
- ASSERT(!prototype->IsMap());
- function->initialize_properties();
- function->initialize_elements();
- function->set_shared(shared);
- function->set_code(shared->code());
- function->set_prototype_or_initial_map(prototype);
- function->set_context(undefined_value());
- function->set_literals_or_bindings(empty_fixed_array());
- function->set_next_function_link(undefined_value());
-}
-
-
-MaybeObject* Heap::AllocateFunction(Map* function_map,
- SharedFunctionInfo* shared,
- Object* prototype,
- PretenureFlag pretenure) {
- AllocationSpace space =
- (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
- Object* result;
- { MaybeObject* maybe_result = Allocate(function_map, space);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- InitializeFunction(JSFunction::cast(result), shared, prototype);
- return result;
-}
-
-
-MaybeObject* Heap::AllocateArgumentsObject(Object* callee, int length) {
+AllocationResult Heap::AllocateArgumentsObject(Object* callee, int length) {
// To get fast allocation and map sharing for arguments objects we
// allocate them based on an arguments boilerplate.
@@ -4422,34 +3591,31 @@ MaybeObject* Heap::AllocateArgumentsObject(Object* callee, int length) {
ASSERT(arguments_object_size == boilerplate->map()->instance_size());
// Do the allocation.
- Object* result;
- { MaybeObject* maybe_result =
+ HeapObject* result;
+ { AllocationResult allocation =
AllocateRaw(arguments_object_size, NEW_SPACE, OLD_POINTER_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ if (!allocation.To(&result)) return allocation;
}
// Copy the content. The arguments boilerplate doesn't have any
// fields that point to new space so it's safe to skip the write
// barrier here.
- CopyBlock(HeapObject::cast(result)->address(),
- boilerplate->address(),
- JSObject::kHeaderSize);
+ CopyBlock(result->address(), boilerplate->address(), JSObject::kHeaderSize);
// Set the length property.
- JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsLengthIndex,
- Smi::FromInt(length),
- SKIP_WRITE_BARRIER);
+ JSObject* js_obj = JSObject::cast(result);
+ js_obj->InObjectPropertyAtPut(
+ kArgumentsLengthIndex, Smi::FromInt(length), SKIP_WRITE_BARRIER);
// Set the callee property for sloppy mode arguments object only.
if (!strict_mode_callee) {
- JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsCalleeIndex,
- callee);
+ js_obj->InObjectPropertyAtPut(kArgumentsCalleeIndex, callee);
}
// Check the state of the object
- ASSERT(JSObject::cast(result)->HasFastProperties());
- ASSERT(JSObject::cast(result)->HasFastObjectElements());
+ ASSERT(js_obj->HasFastProperties());
+ ASSERT(js_obj->HasFastObjectElements());
- return result;
+ return js_obj;
}
@@ -4485,7 +3651,7 @@ void Heap::InitializeJSObjectFromMap(JSObject* obj,
}
-MaybeObject* Heap::AllocateJSObjectFromMap(
+AllocationResult Heap::AllocateJSObjectFromMap(
Map* map,
PretenureFlag pretenure,
bool allocate_properties,
@@ -4504,8 +3670,8 @@ MaybeObject* Heap::AllocateJSObjectFromMap(
if (allocate_properties) {
int prop_size = map->InitialPropertiesLength();
ASSERT(prop_size >= 0);
- { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, pretenure);
- if (!maybe_properties->To(&properties)) return maybe_properties;
+ { AllocationResult allocation = AllocateFixedArray(prop_size, pretenure);
+ if (!allocation.To(&properties)) return allocation;
}
} else {
properties = empty_fixed_array();
@@ -4514,202 +3680,37 @@ MaybeObject* Heap::AllocateJSObjectFromMap(
// Allocate the JSObject.
int size = map->instance_size();
AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, pretenure);
- Object* obj;
- MaybeObject* maybe_obj = Allocate(map, space, allocation_site);
- if (!maybe_obj->To(&obj)) return maybe_obj;
+ JSObject* js_obj;
+ AllocationResult allocation = Allocate(map, space, allocation_site);
+ if (!allocation.To(&js_obj)) return allocation;
// Initialize the JSObject.
- InitializeJSObjectFromMap(JSObject::cast(obj), properties, map);
- ASSERT(JSObject::cast(obj)->HasFastElements() ||
- JSObject::cast(obj)->HasExternalArrayElements() ||
- JSObject::cast(obj)->HasFixedTypedArrayElements());
- return obj;
+ InitializeJSObjectFromMap(js_obj, properties, map);
+ ASSERT(js_obj->HasFastElements() ||
+ js_obj->HasExternalArrayElements() ||
+ js_obj->HasFixedTypedArrayElements());
+ return js_obj;
}
-MaybeObject* Heap::AllocateJSObject(JSFunction* constructor,
- PretenureFlag pretenure,
- AllocationSite* allocation_site) {
+AllocationResult Heap::AllocateJSObject(JSFunction* constructor,
+ PretenureFlag pretenure,
+ AllocationSite* allocation_site) {
ASSERT(constructor->has_initial_map());
// Allocate the object based on the constructors initial map.
- MaybeObject* result = AllocateJSObjectFromMap(constructor->initial_map(),
- pretenure,
- true,
- allocation_site);
+ AllocationResult allocation = AllocateJSObjectFromMap(
+ constructor->initial_map(), pretenure, true, allocation_site);
#ifdef DEBUG
// Make sure result is NOT a global object if valid.
- Object* non_failure;
- ASSERT(!result->ToObject(&non_failure) || !non_failure->IsGlobalObject());
+ HeapObject* obj;
+ ASSERT(!allocation.To(&obj) || !obj->IsGlobalObject());
#endif
- return result;
-}
-
-
-MaybeObject* Heap::AllocateJSModule(Context* context, ScopeInfo* scope_info) {
- // Allocate a fresh map. Modules do not have a prototype.
- Map* map;
- MaybeObject* maybe_map = AllocateMap(JS_MODULE_TYPE, JSModule::kSize);
- if (!maybe_map->To(&map)) return maybe_map;
- // Allocate the object based on the map.
- JSModule* module;
- MaybeObject* maybe_module = AllocateJSObjectFromMap(map, TENURED);
- if (!maybe_module->To(&module)) return maybe_module;
- module->set_context(context);
- module->set_scope_info(scope_info);
- return module;
-}
-
-
-MaybeObject* Heap::AllocateJSArrayAndStorage(
- ElementsKind elements_kind,
- int length,
- int capacity,
- ArrayStorageAllocationMode mode,
- PretenureFlag pretenure) {
- MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure);
- JSArray* array;
- if (!maybe_array->To(&array)) return maybe_array;
-
- // TODO(mvstanton): this body of code is duplicate with AllocateJSArrayStorage
- // for performance reasons.
- ASSERT(capacity >= length);
-
- if (capacity == 0) {
- array->set_length(Smi::FromInt(0));
- array->set_elements(empty_fixed_array());
- return array;
- }
-
- FixedArrayBase* elms;
- MaybeObject* maybe_elms = NULL;
- if (IsFastDoubleElementsKind(elements_kind)) {
- if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
- maybe_elms = AllocateUninitializedFixedDoubleArray(capacity);
- } else {
- ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
- maybe_elms = AllocateFixedDoubleArrayWithHoles(capacity);
- }
- } else {
- ASSERT(IsFastSmiOrObjectElementsKind(elements_kind));
- if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
- maybe_elms = AllocateUninitializedFixedArray(capacity);
- } else {
- ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
- maybe_elms = AllocateFixedArrayWithHoles(capacity);
- }
- }
- if (!maybe_elms->To(&elms)) return maybe_elms;
-
- array->set_elements(elms);
- array->set_length(Smi::FromInt(length));
- return array;
+ return allocation;
}
-MaybeObject* Heap::AllocateJSArrayStorage(
- JSArray* array,
- int length,
- int capacity,
- ArrayStorageAllocationMode mode) {
- ASSERT(capacity >= length);
-
- if (capacity == 0) {
- array->set_length(Smi::FromInt(0));
- array->set_elements(empty_fixed_array());
- return array;
- }
-
- FixedArrayBase* elms;
- MaybeObject* maybe_elms = NULL;
- ElementsKind elements_kind = array->GetElementsKind();
- if (IsFastDoubleElementsKind(elements_kind)) {
- if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
- maybe_elms = AllocateUninitializedFixedDoubleArray(capacity);
- } else {
- ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
- maybe_elms = AllocateFixedDoubleArrayWithHoles(capacity);
- }
- } else {
- ASSERT(IsFastSmiOrObjectElementsKind(elements_kind));
- if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
- maybe_elms = AllocateUninitializedFixedArray(capacity);
- } else {
- ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
- maybe_elms = AllocateFixedArrayWithHoles(capacity);
- }
- }
- if (!maybe_elms->To(&elms)) return maybe_elms;
-
- array->set_elements(elms);
- array->set_length(Smi::FromInt(length));
- return array;
-}
-
-
-MaybeObject* Heap::AllocateJSArrayWithElements(
- FixedArrayBase* elements,
- ElementsKind elements_kind,
- int length,
- PretenureFlag pretenure) {
- MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure);
- JSArray* array;
- if (!maybe_array->To(&array)) return maybe_array;
-
- array->set_elements(elements);
- array->set_length(Smi::FromInt(length));
- array->ValidateElements();
- return array;
-}
-
-
-MaybeObject* Heap::AllocateJSProxy(Object* handler, Object* prototype) {
- // Allocate map.
- // TODO(rossberg): Once we optimize proxies, think about a scheme to share
- // maps. Will probably depend on the identity of the handler object, too.
- Map* map;
- MaybeObject* maybe_map_obj = AllocateMap(JS_PROXY_TYPE, JSProxy::kSize);
- if (!maybe_map_obj->To<Map>(&map)) return maybe_map_obj;
- map->set_prototype(prototype);
-
- // Allocate the proxy object.
- JSProxy* result;
- MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
- if (!maybe_result->To<JSProxy>(&result)) return maybe_result;
- result->InitializeBody(map->instance_size(), Smi::FromInt(0));
- result->set_handler(handler);
- result->set_hash(undefined_value(), SKIP_WRITE_BARRIER);
- return result;
-}
-
-
-MaybeObject* Heap::AllocateJSFunctionProxy(Object* handler,
- Object* call_trap,
- Object* construct_trap,
- Object* prototype) {
- // Allocate map.
- // TODO(rossberg): Once we optimize proxies, think about a scheme to share
- // maps. Will probably depend on the identity of the handler object, too.
- Map* map;
- MaybeObject* maybe_map_obj =
- AllocateMap(JS_FUNCTION_PROXY_TYPE, JSFunctionProxy::kSize);
- if (!maybe_map_obj->To<Map>(&map)) return maybe_map_obj;
- map->set_prototype(prototype);
-
- // Allocate the proxy object.
- JSFunctionProxy* result;
- MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
- if (!maybe_result->To<JSFunctionProxy>(&result)) return maybe_result;
- result->InitializeBody(map->instance_size(), Smi::FromInt(0));
- result->set_handler(handler);
- result->set_hash(undefined_value(), SKIP_WRITE_BARRIER);
- result->set_call_trap(call_trap);
- result->set_construct_trap(construct_trap);
- return result;
-}
-
-
-MaybeObject* Heap::CopyJSObject(JSObject* source, AllocationSite* site) {
+AllocationResult Heap::CopyJSObject(JSObject* source, AllocationSite* site) {
// Never used to copy functions. If functions need to be copied we
// have to be careful to clear the literals array.
SLOW_ASSERT(!source->IsJSFunction());
@@ -4717,7 +3718,7 @@ MaybeObject* Heap::CopyJSObject(JSObject* source, AllocationSite* site) {
// Make the clone.
Map* map = source->map();
int object_size = map->instance_size();
- Object* clone;
+ HeapObject* clone;
ASSERT(site == NULL || AllocationSite::CanTrack(map->instance_type()));
@@ -4726,11 +3727,11 @@ MaybeObject* Heap::CopyJSObject(JSObject* source, AllocationSite* site) {
// If we're forced to always allocate, we use the general allocation
// functions which may leave us with an object in old space.
if (always_allocate()) {
- { MaybeObject* maybe_clone =
+ { AllocationResult allocation =
AllocateRaw(object_size, NEW_SPACE, OLD_POINTER_SPACE);
- if (!maybe_clone->ToObject(&clone)) return maybe_clone;
+ if (!allocation.To(&clone)) return allocation;
}
- Address clone_address = HeapObject::cast(clone)->address();
+ Address clone_address = clone->address();
CopyBlock(clone_address,
source->address(),
object_size);
@@ -4744,14 +3745,14 @@ MaybeObject* Heap::CopyJSObject(JSObject* source, AllocationSite* site) {
{ int adjusted_object_size = site != NULL
? object_size + AllocationMemento::kSize
: object_size;
- MaybeObject* maybe_clone =
+ AllocationResult allocation =
AllocateRaw(adjusted_object_size, NEW_SPACE, NEW_SPACE);
- if (!maybe_clone->ToObject(&clone)) return maybe_clone;
+ if (!allocation.To(&clone)) return allocation;
}
SLOW_ASSERT(InNewSpace(clone));
// Since we know the clone is allocated in new space, we can copy
// the contents without worrying about updating the write barrier.
- CopyBlock(HeapObject::cast(clone)->address(),
+ CopyBlock(clone->address(),
source->address(),
object_size);
@@ -4768,143 +3769,35 @@ MaybeObject* Heap::CopyJSObject(JSObject* source, AllocationSite* site) {
FixedArray* properties = FixedArray::cast(source->properties());
// Update elements if necessary.
if (elements->length() > 0) {
- Object* elem;
- { MaybeObject* maybe_elem;
+ FixedArrayBase* elem;
+ { AllocationResult allocation;
if (elements->map() == fixed_cow_array_map()) {
- maybe_elem = FixedArray::cast(elements);
+ allocation = FixedArray::cast(elements);
} else if (source->HasFastDoubleElements()) {
- maybe_elem = CopyFixedDoubleArray(FixedDoubleArray::cast(elements));
+ allocation = CopyFixedDoubleArray(FixedDoubleArray::cast(elements));
} else {
- maybe_elem = CopyFixedArray(FixedArray::cast(elements));
+ allocation = CopyFixedArray(FixedArray::cast(elements));
}
- if (!maybe_elem->ToObject(&elem)) return maybe_elem;
+ if (!allocation.To(&elem)) return allocation;
}
- JSObject::cast(clone)->set_elements(FixedArrayBase::cast(elem), wb_mode);
+ JSObject::cast(clone)->set_elements(elem, wb_mode);
}
// Update properties if necessary.
if (properties->length() > 0) {
- Object* prop;
- { MaybeObject* maybe_prop = CopyFixedArray(properties);
- if (!maybe_prop->ToObject(&prop)) return maybe_prop;
+ FixedArray* prop;
+ { AllocationResult allocation = CopyFixedArray(properties);
+ if (!allocation.To(&prop)) return allocation;
}
- JSObject::cast(clone)->set_properties(FixedArray::cast(prop), wb_mode);
+ JSObject::cast(clone)->set_properties(prop, wb_mode);
}
// Return the new clone.
return clone;
}
-MaybeObject* Heap::ReinitializeJSReceiver(
- JSReceiver* object, InstanceType type, int size) {
- ASSERT(type >= FIRST_JS_OBJECT_TYPE);
-
- // Allocate fresh map.
- // TODO(rossberg): Once we optimize proxies, cache these maps.
- Map* map;
- MaybeObject* maybe = AllocateMap(type, size);
- if (!maybe->To<Map>(&map)) return maybe;
-
- // Check that the receiver has at least the size of the fresh object.
- int size_difference = object->map()->instance_size() - map->instance_size();
- ASSERT(size_difference >= 0);
-
- map->set_prototype(object->map()->prototype());
-
- // Allocate the backing storage for the properties.
- int prop_size = map->unused_property_fields() - map->inobject_properties();
- Object* properties;
- maybe = AllocateFixedArray(prop_size, TENURED);
- if (!maybe->ToObject(&properties)) return maybe;
-
- // Functions require some allocation, which might fail here.
- SharedFunctionInfo* shared = NULL;
- if (type == JS_FUNCTION_TYPE) {
- String* name;
- OneByteStringKey key(STATIC_ASCII_VECTOR("<freezing call trap>"),
- HashSeed());
- maybe = InternalizeStringWithKey(&key);
- if (!maybe->To<String>(&name)) return maybe;
- maybe = AllocateSharedFunctionInfo(name);
- if (!maybe->To<SharedFunctionInfo>(&shared)) return maybe;
- }
-
- // Because of possible retries of this function after failure,
- // we must NOT fail after this point, where we have changed the type!
-
- // Reset the map for the object.
- object->set_map(map);
- JSObject* jsobj = JSObject::cast(object);
-
- // Reinitialize the object from the constructor map.
- InitializeJSObjectFromMap(jsobj, FixedArray::cast(properties), map);
-
- // Functions require some minimal initialization.
- if (type == JS_FUNCTION_TYPE) {
- map->set_function_with_prototype(true);
- InitializeFunction(JSFunction::cast(object), shared, the_hole_value());
- JSFunction::cast(object)->set_context(
- isolate()->context()->native_context());
- }
-
- // Put in filler if the new object is smaller than the old.
- if (size_difference > 0) {
- CreateFillerObjectAt(
- object->address() + map->instance_size(), size_difference);
- }
-
- return object;
-}
-
-
-MaybeObject* Heap::ReinitializeJSGlobalProxy(JSFunction* constructor,
- JSGlobalProxy* object) {
- ASSERT(constructor->has_initial_map());
- Map* map = constructor->initial_map();
-
- // Check that the already allocated object has the same size and type as
- // objects allocated using the constructor.
- ASSERT(map->instance_size() == object->map()->instance_size());
- ASSERT(map->instance_type() == object->map()->instance_type());
-
- // Allocate the backing storage for the properties.
- int prop_size = map->unused_property_fields() - map->inobject_properties();
- Object* properties;
- { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, TENURED);
- if (!maybe_properties->ToObject(&properties)) return maybe_properties;
- }
-
- // Reset the map for the object.
- object->set_map(constructor->initial_map());
-
- // Reinitialize the object from the constructor map.
- InitializeJSObjectFromMap(object, FixedArray::cast(properties), map);
- return object;
-}
-
-
-MaybeObject* Heap::AllocateStringFromOneByte(Vector<const uint8_t> string,
- PretenureFlag pretenure) {
- int length = string.length();
- if (length == 1) {
- return Heap::LookupSingleCharacterStringFromCode(string[0]);
- }
- Object* result;
- { MaybeObject* maybe_result =
- AllocateRawOneByteString(string.length(), pretenure);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
-
- // Copy the characters into the new object.
- CopyChars(SeqOneByteString::cast(result)->GetChars(),
- string.start(),
- length);
- return result;
-}
-
-
-MaybeObject* Heap::AllocateStringFromUtf8Slow(Vector<const char> string,
- int non_ascii_start,
- PretenureFlag pretenure) {
+AllocationResult Heap::AllocateStringFromUtf8Slow(Vector<const char> string,
+ int non_ascii_start,
+ PretenureFlag pretenure) {
// Continue counting the number of characters in the UTF-8 string, starting
// from the first non-ascii character or word.
Access<UnicodeCache::Utf8Decoder>
@@ -4914,16 +3807,16 @@ MaybeObject* Heap::AllocateStringFromUtf8Slow(Vector<const char> string,
int utf16_length = decoder->Utf16Length();
ASSERT(utf16_length > 0);
// Allocate string.
- Object* result;
+ HeapObject* result;
{
int chars = non_ascii_start + utf16_length;
- MaybeObject* maybe_result = AllocateRawTwoByteString(chars, pretenure);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ AllocationResult allocation = AllocateRawTwoByteString(chars, pretenure);
+ if (!allocation.To(&result) || result->IsException()) {
+ return allocation;
+ }
}
- // Convert and copy the characters into the new object.
- SeqTwoByteString* twobyte = SeqTwoByteString::cast(result);
// Copy ascii portion.
- uint16_t* data = twobyte->GetChars();
+ uint16_t* data = SeqTwoByteString::cast(result)->GetChars();
if (non_ascii_start != 0) {
const char* ascii_data = string.start();
for (int i = 0; i < non_ascii_start; i++) {
@@ -4936,52 +3829,30 @@ MaybeObject* Heap::AllocateStringFromUtf8Slow(Vector<const char> string,
}
-MaybeObject* Heap::AllocateStringFromTwoByte(Vector<const uc16> string,
- PretenureFlag pretenure) {
+AllocationResult Heap::AllocateStringFromTwoByte(Vector<const uc16> string,
+ PretenureFlag pretenure) {
// Check if the string is an ASCII string.
- Object* result;
+ HeapObject* result;
int length = string.length();
const uc16* start = string.start();
if (String::IsOneByte(start, length)) {
- MaybeObject* maybe_result = AllocateRawOneByteString(length, pretenure);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ AllocationResult allocation = AllocateRawOneByteString(length, pretenure);
+ if (!allocation.To(&result) || result->IsException()) {
+ return allocation;
+ }
CopyChars(SeqOneByteString::cast(result)->GetChars(), start, length);
} else { // It's not a one byte string.
- MaybeObject* maybe_result = AllocateRawTwoByteString(length, pretenure);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ AllocationResult allocation = AllocateRawTwoByteString(length, pretenure);
+ if (!allocation.To(&result) || result->IsException()) {
+ return allocation;
+ }
CopyChars(SeqTwoByteString::cast(result)->GetChars(), start, length);
}
return result;
}
-Map* Heap::InternalizedStringMapForString(String* string) {
- // If the string is in new space it cannot be used as internalized.
- if (InNewSpace(string)) return NULL;
-
- // Find the corresponding internalized string map for strings.
- switch (string->map()->instance_type()) {
- case STRING_TYPE: return internalized_string_map();
- case ASCII_STRING_TYPE: return ascii_internalized_string_map();
- case CONS_STRING_TYPE: return cons_internalized_string_map();
- case CONS_ASCII_STRING_TYPE: return cons_ascii_internalized_string_map();
- case EXTERNAL_STRING_TYPE: return external_internalized_string_map();
- case EXTERNAL_ASCII_STRING_TYPE:
- return external_ascii_internalized_string_map();
- case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
- return external_internalized_string_with_one_byte_data_map();
- case SHORT_EXTERNAL_STRING_TYPE:
- return short_external_internalized_string_map();
- case SHORT_EXTERNAL_ASCII_STRING_TYPE:
- return short_external_ascii_internalized_string_map();
- case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
- return short_external_internalized_string_with_one_byte_data_map();
- default: return NULL; // No match found.
- }
-}
-
-
static inline void WriteOneByteData(Vector<const char> vector,
uint8_t* chars,
int len) {
@@ -5031,7 +3902,7 @@ static inline void WriteTwoByteData(String* s, uint16_t* chars, int len) {
template<bool is_one_byte, typename T>
-MaybeObject* Heap::AllocateInternalizedStringImpl(
+AllocationResult Heap::AllocateInternalizedStringImpl(
T t, int chars, uint32_t hash_field) {
ASSERT(chars >= 0);
// Compute map and object size.
@@ -5051,12 +3922,12 @@ MaybeObject* Heap::AllocateInternalizedStringImpl(
AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, TENURED);
// Allocate string.
- Object* result;
- { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ HeapObject* result;
+ { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
+ if (!allocation.To(&result)) return allocation;
}
- reinterpret_cast<HeapObject*>(result)->set_map_no_write_barrier(map);
+ result->set_map_no_write_barrier(map);
// Set length and hash fields of the allocated string.
String* answer = String::cast(result);
answer->set_length(chars);
@@ -5075,17 +3946,18 @@ MaybeObject* Heap::AllocateInternalizedStringImpl(
// Need explicit instantiations.
template
-MaybeObject* Heap::AllocateInternalizedStringImpl<true>(String*, int, uint32_t);
+AllocationResult Heap::AllocateInternalizedStringImpl<true>(
+ String*, int, uint32_t);
template
-MaybeObject* Heap::AllocateInternalizedStringImpl<false>(
+AllocationResult Heap::AllocateInternalizedStringImpl<false>(
String*, int, uint32_t);
template
-MaybeObject* Heap::AllocateInternalizedStringImpl<false>(
+AllocationResult Heap::AllocateInternalizedStringImpl<false>(
Vector<const char>, int, uint32_t);
-MaybeObject* Heap::AllocateRawOneByteString(int length,
- PretenureFlag pretenure) {
+AllocationResult Heap::AllocateRawOneByteString(int length,
+ PretenureFlag pretenure) {
if (length < 0 || length > String::kMaxLength) {
return isolate()->ThrowInvalidStringLength();
}
@@ -5093,13 +3965,13 @@ MaybeObject* Heap::AllocateRawOneByteString(int length,
ASSERT(size <= SeqOneByteString::kMaxSize);
AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure);
- Object* result;
- { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ HeapObject* result;
+ { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
+ if (!allocation.To(&result)) return allocation;
}
// Partially initialize the object.
- HeapObject::cast(result)->set_map_no_write_barrier(ascii_string_map());
+ result->set_map_no_write_barrier(ascii_string_map());
String::cast(result)->set_length(length);
String::cast(result)->set_hash_field(String::kEmptyHashField);
ASSERT_EQ(size, HeapObject::cast(result)->Size());
@@ -5108,8 +3980,8 @@ MaybeObject* Heap::AllocateRawOneByteString(int length,
}
-MaybeObject* Heap::AllocateRawTwoByteString(int length,
- PretenureFlag pretenure) {
+AllocationResult Heap::AllocateRawTwoByteString(int length,
+ PretenureFlag pretenure) {
if (length < 0 || length > String::kMaxLength) {
return isolate()->ThrowInvalidStringLength();
}
@@ -5117,13 +3989,13 @@ MaybeObject* Heap::AllocateRawTwoByteString(int length,
ASSERT(size <= SeqTwoByteString::kMaxSize);
AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure);
- Object* result;
- { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ HeapObject* result;
+ { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
+ if (!allocation.To(&result)) return allocation;
}
// Partially initialize the object.
- HeapObject::cast(result)->set_map_no_write_barrier(string_map());
+ result->set_map_no_write_barrier(string_map());
String::cast(result)->set_length(length);
String::cast(result)->set_hash_field(String::kEmptyHashField);
ASSERT_EQ(size, HeapObject::cast(result)->Size());
@@ -5131,49 +4003,37 @@ MaybeObject* Heap::AllocateRawTwoByteString(int length,
}
-MaybeObject* Heap::AllocateJSArray(
- ElementsKind elements_kind,
- PretenureFlag pretenure) {
- Context* native_context = isolate()->context()->native_context();
- JSFunction* array_function = native_context->array_function();
- Map* map = array_function->initial_map();
- Map* transition_map = isolate()->get_initial_js_array_map(elements_kind);
- if (transition_map != NULL) map = transition_map;
- return AllocateJSObjectFromMap(map, pretenure);
-}
-
-
-MaybeObject* Heap::AllocateEmptyFixedArray() {
+AllocationResult Heap::AllocateEmptyFixedArray() {
int size = FixedArray::SizeFor(0);
- Object* result;
- { MaybeObject* maybe_result =
+ HeapObject* result;
+ { AllocationResult allocation =
AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ if (!allocation.To(&result)) return allocation;
}
// Initialize the object.
- reinterpret_cast<FixedArray*>(result)->set_map_no_write_barrier(
- fixed_array_map());
- reinterpret_cast<FixedArray*>(result)->set_length(0);
+ result->set_map_no_write_barrier(fixed_array_map());
+ FixedArray::cast(result)->set_length(0);
return result;
}
-MaybeObject* Heap::AllocateEmptyExternalArray(ExternalArrayType array_type) {
+AllocationResult Heap::AllocateEmptyExternalArray(
+ ExternalArrayType array_type) {
return AllocateExternalArray(0, array_type, NULL, TENURED);
}
-MaybeObject* Heap::CopyAndTenureFixedCOWArray(FixedArray* src) {
+AllocationResult Heap::CopyAndTenureFixedCOWArray(FixedArray* src) {
if (!InNewSpace(src)) {
return src;
}
int len = src->length();
- Object* obj;
- { MaybeObject* maybe_obj = AllocateRawFixedArray(len, TENURED);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+ HeapObject* obj;
+ { AllocationResult allocation = AllocateRawFixedArray(len, TENURED);
+ if (!allocation.To(&obj)) return allocation;
}
- HeapObject::cast(obj)->set_map_no_write_barrier(fixed_array_map());
+ obj->set_map_no_write_barrier(fixed_array_map());
FixedArray* result = FixedArray::cast(obj);
result->set_length(len);
@@ -5190,26 +4050,26 @@ MaybeObject* Heap::CopyAndTenureFixedCOWArray(FixedArray* src) {
}
-MaybeObject* Heap::AllocateEmptyFixedTypedArray(ExternalArrayType array_type) {
+AllocationResult Heap::AllocateEmptyFixedTypedArray(
+ ExternalArrayType array_type) {
return AllocateFixedTypedArray(0, array_type, TENURED);
}
-MaybeObject* Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) {
+AllocationResult Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) {
int len = src->length();
- Object* obj;
- { MaybeObject* maybe_obj = AllocateRawFixedArray(len, NOT_TENURED);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+ HeapObject* obj;
+ { AllocationResult allocation = AllocateRawFixedArray(len, NOT_TENURED);
+ if (!allocation.To(&obj)) return allocation;
}
if (InNewSpace(obj)) {
- HeapObject* dst = HeapObject::cast(obj);
- dst->set_map_no_write_barrier(map);
- CopyBlock(dst->address() + kPointerSize,
+ obj->set_map_no_write_barrier(map);
+ CopyBlock(obj->address() + kPointerSize,
src->address() + kPointerSize,
FixedArray::SizeFor(len) - kPointerSize);
return obj;
}
- HeapObject::cast(obj)->set_map_no_write_barrier(map);
+ obj->set_map_no_write_barrier(map);
FixedArray* result = FixedArray::cast(obj);
result->set_length(len);
@@ -5221,48 +4081,47 @@ MaybeObject* Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) {
}
-MaybeObject* Heap::CopyFixedDoubleArrayWithMap(FixedDoubleArray* src,
- Map* map) {
+AllocationResult Heap::CopyFixedDoubleArrayWithMap(FixedDoubleArray* src,
+ Map* map) {
int len = src->length();
- Object* obj;
- { MaybeObject* maybe_obj = AllocateRawFixedDoubleArray(len, NOT_TENURED);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+ HeapObject* obj;
+ { AllocationResult allocation = AllocateRawFixedDoubleArray(len, NOT_TENURED);
+ if (!allocation.To(&obj)) return allocation;
}
- HeapObject* dst = HeapObject::cast(obj);
- dst->set_map_no_write_barrier(map);
+ obj->set_map_no_write_barrier(map);
CopyBlock(
- dst->address() + FixedDoubleArray::kLengthOffset,
+ obj->address() + FixedDoubleArray::kLengthOffset,
src->address() + FixedDoubleArray::kLengthOffset,
FixedDoubleArray::SizeFor(len) - FixedDoubleArray::kLengthOffset);
return obj;
}
-MaybeObject* Heap::CopyConstantPoolArrayWithMap(ConstantPoolArray* src,
- Map* map) {
+AllocationResult Heap::CopyConstantPoolArrayWithMap(ConstantPoolArray* src,
+ Map* map) {
int int64_entries = src->count_of_int64_entries();
int code_ptr_entries = src->count_of_code_ptr_entries();
int heap_ptr_entries = src->count_of_heap_ptr_entries();
int int32_entries = src->count_of_int32_entries();
- Object* obj;
- { MaybeObject* maybe_obj =
+ HeapObject* obj;
+ { AllocationResult allocation =
AllocateConstantPoolArray(int64_entries, code_ptr_entries,
heap_ptr_entries, int32_entries);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+ if (!allocation.To(&obj)) return allocation;
}
- HeapObject* dst = HeapObject::cast(obj);
- dst->set_map_no_write_barrier(map);
+ obj->set_map_no_write_barrier(map);
int size = ConstantPoolArray::SizeFor(
int64_entries, code_ptr_entries, heap_ptr_entries, int32_entries);
CopyBlock(
- dst->address() + ConstantPoolArray::kLengthOffset,
+ obj->address() + ConstantPoolArray::kLengthOffset,
src->address() + ConstantPoolArray::kLengthOffset,
size - ConstantPoolArray::kLengthOffset);
return obj;
}
-MaybeObject* Heap::AllocateRawFixedArray(int length, PretenureFlag pretenure) {
+AllocationResult Heap::AllocateRawFixedArray(int length,
+ PretenureFlag pretenure) {
if (length < 0 || length > FixedArray::kMaxLength) {
v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
}
@@ -5273,20 +4132,20 @@ MaybeObject* Heap::AllocateRawFixedArray(int length, PretenureFlag pretenure) {
}
-MaybeObject* Heap::AllocateFixedArrayWithFiller(int length,
- PretenureFlag pretenure,
- Object* filler) {
+AllocationResult Heap::AllocateFixedArrayWithFiller(int length,
+ PretenureFlag pretenure,
+ Object* filler) {
ASSERT(length >= 0);
ASSERT(empty_fixed_array()->IsFixedArray());
if (length == 0) return empty_fixed_array();
ASSERT(!InNewSpace(filler));
- Object* result;
- { MaybeObject* maybe_result = AllocateRawFixedArray(length, pretenure);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ HeapObject* result;
+ { AllocationResult allocation = AllocateRawFixedArray(length, pretenure);
+ if (!allocation.To(&result)) return allocation;
}
- HeapObject::cast(result)->set_map_no_write_barrier(fixed_array_map());
+ result->set_map_no_write_barrier(fixed_array_map());
FixedArray* array = FixedArray::cast(result);
array->set_length(length);
MemsetPointer(array->data_start(), filler, length);
@@ -5294,87 +4153,42 @@ MaybeObject* Heap::AllocateFixedArrayWithFiller(int length,
}
-MaybeObject* Heap::AllocateFixedArray(int length, PretenureFlag pretenure) {
+AllocationResult Heap::AllocateFixedArray(int length, PretenureFlag pretenure) {
return AllocateFixedArrayWithFiller(length, pretenure, undefined_value());
}
-MaybeObject* Heap::AllocateFixedArrayWithHoles(int length,
- PretenureFlag pretenure) {
- return AllocateFixedArrayWithFiller(length, pretenure, the_hole_value());
-}
-
-
-MaybeObject* Heap::AllocateUninitializedFixedArray(int length) {
+AllocationResult Heap::AllocateUninitializedFixedArray(int length) {
if (length == 0) return empty_fixed_array();
- Object* obj;
- { MaybeObject* maybe_obj = AllocateRawFixedArray(length, NOT_TENURED);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+ HeapObject* obj;
+ { AllocationResult allocation = AllocateRawFixedArray(length, NOT_TENURED);
+ if (!allocation.To(&obj)) return allocation;
}
- reinterpret_cast<FixedArray*>(obj)->set_map_no_write_barrier(
- fixed_array_map());
+ obj->set_map_no_write_barrier(fixed_array_map());
FixedArray::cast(obj)->set_length(length);
return obj;
}
-MaybeObject* Heap::AllocateEmptyFixedDoubleArray() {
- int size = FixedDoubleArray::SizeFor(0);
- Object* result;
- { MaybeObject* maybe_result =
- AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- // Initialize the object.
- reinterpret_cast<FixedDoubleArray*>(result)->set_map_no_write_barrier(
- fixed_double_array_map());
- reinterpret_cast<FixedDoubleArray*>(result)->set_length(0);
- return result;
-}
-
-
-MaybeObject* Heap::AllocateUninitializedFixedDoubleArray(
+AllocationResult Heap::AllocateUninitializedFixedDoubleArray(
int length,
PretenureFlag pretenure) {
if (length == 0) return empty_fixed_array();
- Object* elements_object;
- MaybeObject* maybe_obj = AllocateRawFixedDoubleArray(length, pretenure);
- if (!maybe_obj->ToObject(&elements_object)) return maybe_obj;
- FixedDoubleArray* elements =
- reinterpret_cast<FixedDoubleArray*>(elements_object);
+ HeapObject* elements;
+ AllocationResult allocation = AllocateRawFixedDoubleArray(length, pretenure);
+ if (!allocation.To(&elements)) return allocation;
elements->set_map_no_write_barrier(fixed_double_array_map());
- elements->set_length(length);
+ FixedDoubleArray::cast(elements)->set_length(length);
return elements;
}
-MaybeObject* Heap::AllocateFixedDoubleArrayWithHoles(
- int length,
- PretenureFlag pretenure) {
- if (length == 0) return empty_fixed_array();
-
- Object* elements_object;
- MaybeObject* maybe_obj = AllocateRawFixedDoubleArray(length, pretenure);
- if (!maybe_obj->ToObject(&elements_object)) return maybe_obj;
- FixedDoubleArray* elements =
- reinterpret_cast<FixedDoubleArray*>(elements_object);
-
- for (int i = 0; i < length; ++i) {
- elements->set_the_hole(i);
- }
-
- elements->set_map_no_write_barrier(fixed_double_array_map());
- elements->set_length(length);
- return elements;
-}
-
-
-MaybeObject* Heap::AllocateRawFixedDoubleArray(int length,
- PretenureFlag pretenure) {
+AllocationResult Heap::AllocateRawFixedDoubleArray(int length,
+ PretenureFlag pretenure) {
if (length < 0 || length > FixedDoubleArray::kMaxLength) {
v8::internal::Heap::FatalProcessOutOfMemory("invalid array length", true);
}
@@ -5385,20 +4199,26 @@ MaybeObject* Heap::AllocateRawFixedDoubleArray(int length,
AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure);
HeapObject* object;
- { MaybeObject* maybe_object = AllocateRaw(size, space, OLD_DATA_SPACE);
- if (!maybe_object->To<HeapObject>(&object)) return maybe_object;
+ { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
+ if (!allocation.To(&object)) return allocation;
}
return EnsureDoubleAligned(this, object, size);
}
-MaybeObject* Heap::AllocateConstantPoolArray(int number_of_int64_entries,
- int number_of_code_ptr_entries,
- int number_of_heap_ptr_entries,
- int number_of_int32_entries) {
- ASSERT(number_of_int64_entries > 0 || number_of_code_ptr_entries > 0 ||
- number_of_heap_ptr_entries > 0 || number_of_int32_entries > 0);
+AllocationResult Heap::AllocateConstantPoolArray(int number_of_int64_entries,
+ int number_of_code_ptr_entries,
+ int number_of_heap_ptr_entries,
+ int number_of_int32_entries) {
+ CHECK(number_of_int64_entries >= 0 &&
+ number_of_int64_entries <= ConstantPoolArray::kMaxEntriesPerType &&
+ number_of_code_ptr_entries >= 0 &&
+ number_of_code_ptr_entries <= ConstantPoolArray::kMaxEntriesPerType &&
+ number_of_heap_ptr_entries >= 0 &&
+ number_of_heap_ptr_entries <= ConstantPoolArray::kMaxEntriesPerType &&
+ number_of_int32_entries >= 0 &&
+ number_of_int32_entries <= ConstantPoolArray::kMaxEntriesPerType);
int size = ConstantPoolArray::SizeFor(number_of_int64_entries,
number_of_code_ptr_entries,
number_of_heap_ptr_entries,
@@ -5409,18 +4229,17 @@ MaybeObject* Heap::AllocateConstantPoolArray(int number_of_int64_entries,
AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, TENURED);
HeapObject* object;
- { MaybeObject* maybe_object = AllocateRaw(size, space, OLD_POINTER_SPACE);
- if (!maybe_object->To<HeapObject>(&object)) return maybe_object;
+ { AllocationResult allocation = AllocateRaw(size, space, OLD_POINTER_SPACE);
+ if (!allocation.To(&object)) return allocation;
}
object = EnsureDoubleAligned(this, object, size);
- HeapObject::cast(object)->set_map_no_write_barrier(constant_pool_array_map());
-
- ConstantPoolArray* constant_pool =
- reinterpret_cast<ConstantPoolArray*>(object);
- constant_pool->SetEntryCounts(number_of_int64_entries,
- number_of_code_ptr_entries,
- number_of_heap_ptr_entries,
- number_of_int32_entries);
+ object->set_map_no_write_barrier(constant_pool_array_map());
+
+ ConstantPoolArray* constant_pool = ConstantPoolArray::cast(object);
+ constant_pool->Init(number_of_int64_entries,
+ number_of_code_ptr_entries,
+ number_of_heap_ptr_entries,
+ number_of_int32_entries);
if (number_of_code_ptr_entries > 0) {
int offset =
constant_pool->OffsetOfElementAt(constant_pool->first_code_ptr_index());
@@ -5441,41 +4260,29 @@ MaybeObject* Heap::AllocateConstantPoolArray(int number_of_int64_entries,
}
-MaybeObject* Heap::AllocateEmptyConstantPoolArray() {
+AllocationResult Heap::AllocateEmptyConstantPoolArray() {
int size = ConstantPoolArray::SizeFor(0, 0, 0, 0);
- Object* result;
- { MaybeObject* maybe_result =
+ HeapObject* result;
+ { AllocationResult allocation =
AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- HeapObject::cast(result)->set_map_no_write_barrier(constant_pool_array_map());
- ConstantPoolArray::cast(result)->SetEntryCounts(0, 0, 0, 0);
- return result;
-}
-
-
-MaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) {
- Object* result;
- { MaybeObject* maybe_result = AllocateFixedArray(length, pretenure);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ if (!allocation.To(&result)) return allocation;
}
- reinterpret_cast<HeapObject*>(result)->set_map_no_write_barrier(
- hash_table_map());
- ASSERT(result->IsHashTable());
+ result->set_map_no_write_barrier(constant_pool_array_map());
+ ConstantPoolArray::cast(result)->Init(0, 0, 0, 0);
return result;
}
-MaybeObject* Heap::AllocateSymbol() {
+AllocationResult Heap::AllocateSymbol() {
// Statically ensure that it is safe to allocate symbols in paged spaces.
STATIC_ASSERT(Symbol::kSize <= Page::kMaxRegularHeapObjectSize);
- Object* result;
- MaybeObject* maybe =
+ HeapObject* result;
+ AllocationResult allocation =
AllocateRaw(Symbol::kSize, OLD_POINTER_SPACE, OLD_POINTER_SPACE);
- if (!maybe->ToObject(&result)) return maybe;
+ if (!allocation.To(&result)) return allocation;
- HeapObject::cast(result)->set_map_no_write_barrier(symbol_map());
+ result->set_map_no_write_barrier(symbol_map());
// Generate a random hash value.
int hash;
@@ -5496,159 +4303,7 @@ MaybeObject* Heap::AllocateSymbol() {
}
-MaybeObject* Heap::AllocatePrivateSymbol() {
- MaybeObject* maybe = AllocateSymbol();
- Symbol* symbol;
- if (!maybe->To(&symbol)) return maybe;
- symbol->set_is_private(true);
- return symbol;
-}
-
-
-MaybeObject* Heap::AllocateNativeContext() {
- Object* result;
- { MaybeObject* maybe_result =
- AllocateFixedArray(Context::NATIVE_CONTEXT_SLOTS);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- Context* context = reinterpret_cast<Context*>(result);
- context->set_map_no_write_barrier(native_context_map());
- context->set_js_array_maps(undefined_value());
- ASSERT(context->IsNativeContext());
- ASSERT(result->IsContext());
- return result;
-}
-
-
-MaybeObject* Heap::AllocateGlobalContext(JSFunction* function,
- ScopeInfo* scope_info) {
- Object* result;
- { MaybeObject* maybe_result =
- AllocateFixedArray(scope_info->ContextLength(), TENURED);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- Context* context = reinterpret_cast<Context*>(result);
- context->set_map_no_write_barrier(global_context_map());
- context->set_closure(function);
- context->set_previous(function->context());
- context->set_extension(scope_info);
- context->set_global_object(function->context()->global_object());
- ASSERT(context->IsGlobalContext());
- ASSERT(result->IsContext());
- return context;
-}
-
-
-MaybeObject* Heap::AllocateModuleContext(ScopeInfo* scope_info) {
- Object* result;
- { MaybeObject* maybe_result =
- AllocateFixedArray(scope_info->ContextLength(), TENURED);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- Context* context = reinterpret_cast<Context*>(result);
- context->set_map_no_write_barrier(module_context_map());
- // Instance link will be set later.
- context->set_extension(Smi::FromInt(0));
- return context;
-}
-
-
-MaybeObject* Heap::AllocateFunctionContext(int length, JSFunction* function) {
- ASSERT(length >= Context::MIN_CONTEXT_SLOTS);
- Object* result;
- { MaybeObject* maybe_result = AllocateFixedArray(length);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- Context* context = reinterpret_cast<Context*>(result);
- context->set_map_no_write_barrier(function_context_map());
- context->set_closure(function);
- context->set_previous(function->context());
- context->set_extension(Smi::FromInt(0));
- context->set_global_object(function->context()->global_object());
- return context;
-}
-
-
-MaybeObject* Heap::AllocateCatchContext(JSFunction* function,
- Context* previous,
- String* name,
- Object* thrown_object) {
- STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == Context::THROWN_OBJECT_INDEX);
- Object* result;
- { MaybeObject* maybe_result =
- AllocateFixedArray(Context::MIN_CONTEXT_SLOTS + 1);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- Context* context = reinterpret_cast<Context*>(result);
- context->set_map_no_write_barrier(catch_context_map());
- context->set_closure(function);
- context->set_previous(previous);
- context->set_extension(name);
- context->set_global_object(previous->global_object());
- context->set(Context::THROWN_OBJECT_INDEX, thrown_object);
- return context;
-}
-
-
-MaybeObject* Heap::AllocateWithContext(JSFunction* function,
- Context* previous,
- JSReceiver* extension) {
- Object* result;
- { MaybeObject* maybe_result = AllocateFixedArray(Context::MIN_CONTEXT_SLOTS);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- Context* context = reinterpret_cast<Context*>(result);
- context->set_map_no_write_barrier(with_context_map());
- context->set_closure(function);
- context->set_previous(previous);
- context->set_extension(extension);
- context->set_global_object(previous->global_object());
- return context;
-}
-
-
-MaybeObject* Heap::AllocateBlockContext(JSFunction* function,
- Context* previous,
- ScopeInfo* scope_info) {
- Object* result;
- { MaybeObject* maybe_result =
- AllocateFixedArrayWithHoles(scope_info->ContextLength());
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- Context* context = reinterpret_cast<Context*>(result);
- context->set_map_no_write_barrier(block_context_map());
- context->set_closure(function);
- context->set_previous(previous);
- context->set_extension(scope_info);
- context->set_global_object(previous->global_object());
- return context;
-}
-
-
-MaybeObject* Heap::AllocateScopeInfo(int length) {
- FixedArray* scope_info;
- MaybeObject* maybe_scope_info = AllocateFixedArray(length, TENURED);
- if (!maybe_scope_info->To(&scope_info)) return maybe_scope_info;
- scope_info->set_map_no_write_barrier(scope_info_map());
- return scope_info;
-}
-
-
-MaybeObject* Heap::AllocateExternal(void* value) {
- Foreign* foreign;
- { MaybeObject* maybe_result = AllocateForeign(static_cast<Address>(value));
- if (!maybe_result->To(&foreign)) return maybe_result;
- }
- JSObject* external;
- { MaybeObject* maybe_result = AllocateJSObjectFromMap(external_map());
- if (!maybe_result->To(&external)) return maybe_result;
- }
- external->SetInternalField(0, foreign);
- return external;
-}
-
-
-MaybeObject* Heap::AllocateStruct(InstanceType type) {
+AllocationResult Heap::AllocateStruct(InstanceType type) {
Map* map;
switch (type) {
#define MAKE_CASE(NAME, Name, name) \
@@ -5657,15 +4312,15 @@ STRUCT_LIST(MAKE_CASE)
#undef MAKE_CASE
default:
UNREACHABLE();
- return Failure::InternalError();
+ return exception();
}
int size = map->instance_size();
AllocationSpace space = SelectSpace(size, OLD_POINTER_SPACE, TENURED);
- Object* result;
- { MaybeObject* maybe_result = Allocate(map, space);
- if (!maybe_result->ToObject(&result)) return maybe_result;
+ Struct* result;
+ { AllocationResult allocation = Allocate(map, space);
+ if (!allocation.To(&result)) return allocation;
}
- Struct::cast(result)->InitializeBody(size);
+ result->InitializeBody(size);
return result;
}
@@ -5740,7 +4395,7 @@ bool Heap::IdleNotification(int hint) {
return false;
}
- if (!FLAG_incremental_marking || Serializer::enabled()) {
+ if (!FLAG_incremental_marking || Serializer::enabled(isolate_)) {
return IdleGlobalGC();
}
@@ -5750,17 +4405,8 @@ bool Heap::IdleNotification(int hint) {
// An incremental GC progresses as follows:
// 1. many incremental marking steps,
// 2. one old space mark-sweep-compact,
- // 3. many lazy sweep steps.
// Use mark-sweep-compact events to count incremental GCs in a round.
- if (incremental_marking()->IsStopped()) {
- if (!mark_compact_collector()->AreSweeperThreadsActivated() &&
- !IsSweepingComplete() &&
- !AdvanceSweepers(static_cast<int>(step_size))) {
- return false;
- }
- }
-
if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) {
if (EnoughGarbageSinceLastIdleRound()) {
StartIdleRound();
@@ -5796,6 +4442,13 @@ bool Heap::IdleNotification(int hint) {
return true;
}
+ // If the IdleNotifcation is called with a large hint we will wait for
+ // the sweepter threads here.
+ if (hint >= kMinHintForFullGC &&
+ mark_compact_collector()->IsConcurrentSweepingInProgress()) {
+ mark_compact_collector()->WaitUntilSweepingCompleted();
+ }
+
return false;
}
@@ -5966,8 +4619,10 @@ bool Heap::InSpace(Address addr, AllocationSpace space) {
return property_cell_space_->Contains(addr);
case LO_SPACE:
return lo_space_->SlowContains(addr);
+ case INVALID_SPACE:
+ break;
}
-
+ UNREACHABLE();
return false;
}
@@ -5975,6 +4630,7 @@ bool Heap::InSpace(Address addr, AllocationSpace space) {
#ifdef VERIFY_HEAP
void Heap::Verify() {
CHECK(HasBeenSetUp());
+ HandleScope scope(isolate());
store_buffer()->Verify();
@@ -6000,52 +4656,6 @@ void Heap::Verify() {
#endif
-MaybeObject* Heap::InternalizeUtf8String(Vector<const char> string) {
- Utf8StringKey key(string, HashSeed());
- return InternalizeStringWithKey(&key);
-}
-
-
-MaybeObject* Heap::InternalizeString(String* string) {
- if (string->IsInternalizedString()) return string;
- Object* result = NULL;
- Object* new_table;
- { MaybeObject* maybe_new_table =
- string_table()->LookupString(string, &result);
- if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table;
- }
- // Can't use set_string_table because StringTable::cast knows that
- // StringTable is a singleton and checks for identity.
- roots_[kStringTableRootIndex] = new_table;
- ASSERT(result != NULL);
- return result;
-}
-
-
-bool Heap::InternalizeStringIfExists(String* string, String** result) {
- if (string->IsInternalizedString()) {
- *result = string;
- return true;
- }
- return string_table()->LookupStringIfExists(string, result);
-}
-
-
-MaybeObject* Heap::InternalizeStringWithKey(HashTableKey* key) {
- Object* result = NULL;
- Object* new_table;
- { MaybeObject* maybe_new_table =
- string_table()->LookupKey(key, &result);
- if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table;
- }
- // Can't use set_string_table because StringTable::cast knows that
- // StringTable is a singleton and checks for identity.
- roots_[kStringTableRootIndex] = new_table;
- ASSERT(result != NULL);
- return result;
-}
-
-
void Heap::ZapFromSpace() {
NewSpacePageIterator it(new_space_.FromSpaceStart(),
new_space_.FromSpaceEnd());
@@ -6303,12 +4913,9 @@ void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
Relocatable::Iterate(isolate_, v);
v->Synchronize(VisitorSynchronization::kRelocatable);
-#ifdef ENABLE_DEBUGGER_SUPPORT
- isolate_->debug()->Iterate(v);
if (isolate_->deoptimizer_data() != NULL) {
isolate_->deoptimizer_data()->Iterate(v);
}
-#endif
v->Synchronize(VisitorSynchronization::kDebug);
isolate_->compilation_cache()->Iterate(v);
v->Synchronize(VisitorSynchronization::kCompilationCache);
@@ -6373,10 +4980,22 @@ void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
// and through the API, we should gracefully handle the case that the heap
// size is not big enough to fit all the initial objects.
bool Heap::ConfigureHeap(int max_semispace_size,
- intptr_t max_old_gen_size,
- intptr_t max_executable_size) {
+ intptr_t max_old_space_size,
+ intptr_t max_executable_size,
+ intptr_t code_range_size) {
if (HasBeenSetUp()) return false;
+ // If max space size flags are specified overwrite the configuration.
+ if (FLAG_max_new_space_size > 0) {
+ max_semispace_size = (FLAG_max_new_space_size / 2) * kLumpOfMemory;
+ }
+ if (FLAG_max_old_space_size > 0) {
+ max_old_space_size = FLAG_max_old_space_size * kLumpOfMemory;
+ }
+ if (FLAG_max_executable_size > 0) {
+ max_executable_size = FLAG_max_executable_size * kLumpOfMemory;
+ }
+
if (FLAG_stress_compaction) {
// This will cause more frequent GCs when stressing.
max_semispace_size_ = Page::kPageSize;
@@ -6412,7 +5031,7 @@ bool Heap::ConfigureHeap(int max_semispace_size,
reserved_semispace_size_ = max_semispace_size_;
}
- if (max_old_gen_size > 0) max_old_generation_size_ = max_old_gen_size;
+ if (max_old_space_size > 0) max_old_generation_size_ = max_old_space_size;
if (max_executable_size > 0) {
max_executable_size_ = RoundUp(max_executable_size, Page::kPageSize);
}
@@ -6448,6 +5067,14 @@ bool Heap::ConfigureHeap(int max_semispace_size,
FixedArray::SizeFor(JSObject::kInitialMaxFastElementArray) +
AllocationMemento::kSize));
+ code_range_size_ = code_range_size;
+
+ // We set the old generation growing factor to 2 to grow the heap slower on
+ // memory-constrained devices.
+ if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) {
+ old_space_growing_factor_ = 2;
+ }
+
configured_ = true;
return true;
}
@@ -6456,7 +5083,8 @@ bool Heap::ConfigureHeap(int max_semispace_size,
bool Heap::ConfigureHeapDefault() {
return ConfigureHeap(static_cast<intptr_t>(FLAG_max_new_space_size / 2) * KB,
static_cast<intptr_t>(FLAG_max_old_space_size) * MB,
- static_cast<intptr_t>(FLAG_max_executable_size) * MB);
+ static_cast<intptr_t>(FLAG_max_executable_size) * MB,
+ static_cast<intptr_t>(0));
}
@@ -6510,14 +5138,6 @@ intptr_t Heap::PromotedSpaceSizeOfObjects() {
}
-bool Heap::AdvanceSweepers(int step_size) {
- ASSERT(!mark_compact_collector()->AreSweeperThreadsActivated());
- bool sweeping_complete = old_data_space()->AdvanceSweeper(step_size);
- sweeping_complete &= old_pointer_space()->AdvanceSweeper(step_size);
- return sweeping_complete;
-}
-
-
int64_t Heap::PromotedExternalMemorySize() {
if (amount_of_external_allocated_memory_
<= amount_of_external_allocated_memory_at_last_global_gc_) return 0;
@@ -6609,16 +5229,10 @@ bool Heap::SetUp() {
if (old_data_space_ == NULL) return false;
if (!old_data_space_->SetUp()) return false;
+ if (!isolate_->code_range()->SetUp(code_range_size_)) return false;
+
// Initialize the code space, set its maximum capacity to the old
// generation size. It needs executable memory.
- // On 64-bit platform(s), we put all code objects in a 2 GB range of
- // virtual address space, so that they can call each other with near calls.
- if (code_range_size_ > 0) {
- if (!isolate_->code_range()->SetUp(code_range_size_)) {
- return false;
- }
- }
-
code_space_ =
new OldSpace(this, max_old_generation_size_, CODE_SPACE, EXECUTABLE);
if (code_space_ == NULL) return false;
@@ -6672,10 +5286,11 @@ bool Heap::SetUp() {
bool Heap::CreateHeapObjects() {
// Create initial maps.
if (!CreateInitialMaps()) return false;
- if (!CreateApiObjects()) return false;
+ CreateApiObjects();
// Create initial objects
- if (!CreateInitialObjects()) return false;
+ CreateInitialObjects();
+ CHECK_EQ(0, gc_count_);
native_contexts_list_ = undefined_value();
array_buffers_list_ = undefined_value();
@@ -6853,24 +5468,25 @@ void Heap::RemoveGCEpilogueCallback(v8::Isolate::GCEpilogueCallback callback) {
}
-MaybeObject* Heap::AddWeakObjectToCodeDependency(Object* obj,
- DependentCode* dep) {
- ASSERT(!InNewSpace(obj));
- ASSERT(!InNewSpace(dep));
- MaybeObject* maybe_obj =
- WeakHashTable::cast(weak_object_to_code_table_)->Put(obj, dep);
- WeakHashTable* table;
- if (!maybe_obj->To(&table)) return maybe_obj;
- if (ShouldZapGarbage() && weak_object_to_code_table_ != table) {
+// TODO(ishell): Find a better place for this.
+void Heap::AddWeakObjectToCodeDependency(Handle<Object> obj,
+ Handle<DependentCode> dep) {
+ ASSERT(!InNewSpace(*obj));
+ ASSERT(!InNewSpace(*dep));
+ HandleScope scope(isolate());
+ Handle<WeakHashTable> table(WeakHashTable::cast(weak_object_to_code_table_),
+ isolate());
+ table = WeakHashTable::Put(table, obj, dep);
+
+ if (ShouldZapGarbage() && weak_object_to_code_table_ != *table) {
WeakHashTable::cast(weak_object_to_code_table_)->Zap(the_hole_value());
}
- set_weak_object_to_code_table(table);
- ASSERT_EQ(dep, WeakHashTable::cast(weak_object_to_code_table_)->Lookup(obj));
- return weak_object_to_code_table_;
+ set_weak_object_to_code_table(*table);
+ ASSERT_EQ(*dep, table->Lookup(obj));
}
-DependentCode* Heap::LookupWeakObjectToCodeDependency(Object* obj) {
+DependentCode* Heap::LookupWeakObjectToCodeDependency(Handle<Object> obj) {
Object* dep = WeakHashTable::cast(weak_object_to_code_table_)->Lookup(obj);
if (dep->IsDependentCode()) return DependentCode::cast(dep);
return DependentCode::cast(empty_fixed_array());
@@ -6879,7 +5495,8 @@ DependentCode* Heap::LookupWeakObjectToCodeDependency(Object* obj) {
void Heap::EnsureWeakObjectToCodeTable() {
if (!weak_object_to_code_table()->IsHashTable()) {
- set_weak_object_to_code_table(*isolate()->factory()->NewWeakHashTable(16));
+ set_weak_object_to_code_table(*WeakHashTable::New(
+ isolate(), 16, USE_DEFAULT_MINIMUM_CAPACITY, TENURED));
}
}
@@ -7603,19 +6220,21 @@ const char* GCTracer::CollectorString() {
}
-int KeyedLookupCache::Hash(Map* map, Name* name) {
+int KeyedLookupCache::Hash(Handle<Map> map, Handle<Name> name) {
+ DisallowHeapAllocation no_gc;
// Uses only lower 32 bits if pointers are larger.
uintptr_t addr_hash =
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map)) >> kMapHashShift;
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(*map)) >> kMapHashShift;
return static_cast<uint32_t>((addr_hash ^ name->Hash()) & kCapacityMask);
}
-int KeyedLookupCache::Lookup(Map* map, Name* name) {
+int KeyedLookupCache::Lookup(Handle<Map> map, Handle<Name> name) {
+ DisallowHeapAllocation no_gc;
int index = (Hash(map, name) & kHashMask);
for (int i = 0; i < kEntriesPerBucket; i++) {
Key& key = keys_[index + i];
- if ((key.map == map) && key.name->Equals(name)) {
+ if ((key.map == *map) && key.name->Equals(*name)) {
return field_offsets_[index + i];
}
}
@@ -7623,18 +6242,20 @@ int KeyedLookupCache::Lookup(Map* map, Name* name) {
}
-void KeyedLookupCache::Update(Map* map, Name* name, int field_offset) {
+void KeyedLookupCache::Update(Handle<Map> map,
+ Handle<Name> name,
+ int field_offset) {
+ DisallowHeapAllocation no_gc;
if (!name->IsUniqueName()) {
- String* internalized_string;
- if (!map->GetIsolate()->heap()->InternalizeStringIfExists(
- String::cast(name), &internalized_string)) {
+ if (!StringTable::InternalizeStringIfExists(name->GetIsolate(),
+ Handle<String>::cast(name)).
+ ToHandle(&name)) {
return;
}
- name = internalized_string;
}
// This cache is cleared only between mark compact passes, so we expect the
// cache to only contain old space names.
- ASSERT(!map->GetIsolate()->heap()->InNewSpace(name));
+ ASSERT(!map->GetIsolate()->heap()->InNewSpace(*name));
int index = (Hash(map, name) & kHashMask);
// After a GC there will be free slots, so we use them in order (this may
@@ -7643,8 +6264,8 @@ void KeyedLookupCache::Update(Map* map, Name* name, int field_offset) {
Key& key = keys_[index];
Object* free_entry_indicator = NULL;
if (key.map == free_entry_indicator) {
- key.map = map;
- key.name = name;
+ key.map = *map;
+ key.name = *name;
field_offsets_[index + i] = field_offset;
return;
}
@@ -7660,8 +6281,8 @@ void KeyedLookupCache::Update(Map* map, Name* name, int field_offset) {
// Write the new first entry.
Key& key = keys_[index];
- key.map = map;
- key.name = name;
+ key.map = *map;
+ key.name = *name;
field_offsets_[index] = field_offset;
}
@@ -7676,16 +6297,6 @@ void DescriptorLookupCache::Clear() {
}
-#ifdef DEBUG
-void Heap::GarbageCollectionGreedyCheck() {
- ASSERT(FLAG_gc_greedy);
- if (isolate_->bootstrapper()->IsActive()) return;
- if (!AllowAllocationFailure::IsAllowed(isolate_)) return;
- CollectGarbage(NEW_SPACE);
-}
-#endif
-
-
void ExternalStringTable::CleanUp() {
int last = 0;
for (int i = 0; i < new_space_strings_.length(); ++i) {
diff --git a/deps/v8/src/heap.h b/deps/v8/src/heap.h
index 0f586e9284..9c100fcf1f 100644
--- a/deps/v8/src/heap.h
+++ b/deps/v8/src/heap.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HEAP_H_
#define V8_HEAP_H_
@@ -32,6 +9,7 @@
#include "allocation.h"
#include "assert-scope.h"
+#include "counters.h"
#include "globals.h"
#include "incremental-marking.h"
#include "list.h"
@@ -40,7 +18,6 @@
#include "spaces.h"
#include "splay-tree-inl.h"
#include "store-buffer.h"
-#include "v8-counters.h"
#include "v8globals.h"
namespace v8 {
@@ -60,6 +37,7 @@ namespace internal {
V(Oddball, true_value, TrueValue) \
V(Oddball, false_value, FalseValue) \
V(Oddball, uninitialized_value, UninitializedValue) \
+ V(Oddball, exception, Exception) \
V(Map, cell_map, CellMap) \
V(Map, global_property_cell_map, GlobalPropertyCellMap) \
V(Map, shared_function_info_map, SharedFunctionInfoMap) \
@@ -72,8 +50,9 @@ namespace internal {
V(Map, fixed_cow_array_map, FixedCOWArrayMap) \
V(Map, fixed_double_array_map, FixedDoubleArrayMap) \
V(Map, constant_pool_array_map, ConstantPoolArrayMap) \
- V(Object, no_interceptor_result_sentinel, NoInterceptorResultSentinel) \
+ V(Oddball, no_interceptor_result_sentinel, NoInterceptorResultSentinel) \
V(Map, hash_table_map, HashTableMap) \
+ V(Map, ordered_hash_table_map, OrderedHashTableMap) \
V(FixedArray, empty_fixed_array, EmptyFixedArray) \
V(ByteArray, empty_byte_array, EmptyByteArray) \
V(DescriptorArray, empty_descriptor_array, EmptyDescriptorArray) \
@@ -89,7 +68,7 @@ namespace internal {
V(FixedArray, single_character_string_cache, SingleCharacterStringCache) \
V(FixedArray, string_split_cache, StringSplitCache) \
V(FixedArray, regexp_multiple_cache, RegExpMultipleCache) \
- V(Object, termination_exception, TerminationException) \
+ V(Oddball, termination_exception, TerminationException) \
V(Smi, hash_seed, HashSeed) \
V(Map, symbol_map, SymbolMap) \
V(Map, string_map, StringMap) \
@@ -109,8 +88,6 @@ namespace internal {
ShortExternalStringWithOneByteDataMap) \
V(Map, internalized_string_map, InternalizedStringMap) \
V(Map, ascii_internalized_string_map, AsciiInternalizedStringMap) \
- V(Map, cons_internalized_string_map, ConsInternalizedStringMap) \
- V(Map, cons_ascii_internalized_string_map, ConsAsciiInternalizedStringMap) \
V(Map, \
external_internalized_string_map, \
ExternalInternalizedStringMap) \
@@ -181,7 +158,15 @@ namespace internal {
V(Map, block_context_map, BlockContextMap) \
V(Map, module_context_map, ModuleContextMap) \
V(Map, global_context_map, GlobalContextMap) \
- V(Map, oddball_map, OddballMap) \
+ V(Map, undefined_map, UndefinedMap) \
+ V(Map, the_hole_map, TheHoleMap) \
+ V(Map, null_map, NullMap) \
+ V(Map, boolean_map, BooleanMap) \
+ V(Map, uninitialized_map, UninitializedMap) \
+ V(Map, arguments_marker_map, ArgumentsMarkerMap) \
+ V(Map, no_interceptor_result_sentinel_map, NoInterceptorResultSentinelMap) \
+ V(Map, exception_map, ExceptionMap) \
+ V(Map, termination_exception_map, TerminationExceptionMap) \
V(Map, message_object_map, JSMessageObjectMap) \
V(Map, foreign_map, ForeignMap) \
V(HeapNumber, nan_value, NanValue) \
@@ -255,6 +240,7 @@ namespace internal {
V(constant_pool_array_map) \
V(no_interceptor_result_sentinel) \
V(hash_table_map) \
+ V(ordered_hash_table_map) \
V(empty_fixed_array) \
V(empty_byte_array) \
V(empty_descriptor_array) \
@@ -268,7 +254,11 @@ namespace internal {
V(block_context_map) \
V(module_context_map) \
V(global_context_map) \
- V(oddball_map) \
+ V(undefined_map) \
+ V(the_hole_map) \
+ V(null_map) \
+ V(boolean_map) \
+ V(uninitialized_map) \
V(message_object_map) \
V(foreign_map) \
V(neander_map)
@@ -337,7 +327,6 @@ namespace internal {
"KeyedStoreElementMonomorphic") \
V(stack_overflow_string, "kStackOverflowBoilerplate") \
V(illegal_access_string, "illegal access") \
- V(illegal_execution_state_string, "illegal execution state") \
V(get_string, "get") \
V(set_string, "set") \
V(map_field_string, "%map") \
@@ -349,11 +338,7 @@ namespace internal {
V(MakeReferenceError_string, "MakeReferenceError") \
V(MakeSyntaxError_string, "MakeSyntaxError") \
V(MakeTypeError_string, "MakeTypeError") \
- V(illegal_return_string, "illegal_return") \
- V(illegal_break_string, "illegal_break") \
- V(illegal_continue_string, "illegal_continue") \
V(unknown_label_string, "unknown_label") \
- V(redeclaration_string, "redeclaration") \
V(space_string, " ") \
V(exec_string, "exec") \
V(zero_string, "0") \
@@ -376,7 +361,9 @@ namespace internal {
V(next_string, "next") \
V(byte_length_string, "byteLength") \
V(byte_offset_string, "byteOffset") \
- V(buffer_string, "buffer")
+ V(buffer_string, "buffer") \
+ V(intl_initialized_marker_string, "v8::intl_initialized_marker") \
+ V(intl_impl_object_string, "v8::intl_object")
// Forward declarations.
class GCTracer;
@@ -562,8 +549,9 @@ class Heap {
// Configure heap size before setup. Return false if the heap has been
// set up already.
bool ConfigureHeap(int max_semispace_size,
- intptr_t max_old_gen_size,
- intptr_t max_executable_size);
+ intptr_t max_old_space_size,
+ intptr_t max_executable_size,
+ intptr_t code_range_size);
bool ConfigureHeapDefault();
// Prepares the heap, setting up memory areas that are needed in the isolate
@@ -694,145 +682,11 @@ class Heap {
return old_data_space_->allocation_limit_address();
}
- // Allocates and initializes a new JavaScript object based on a
- // constructor.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // If allocation_site is non-null, then a memento is emitted after the object
- // that points to the site.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateJSObject(
- JSFunction* constructor,
- PretenureFlag pretenure = NOT_TENURED,
- AllocationSite* allocation_site = NULL);
-
- MUST_USE_RESULT MaybeObject* AllocateJSModule(Context* context,
- ScopeInfo* scope_info);
-
- // Allocate a JSArray with no elements
- MUST_USE_RESULT MaybeObject* AllocateEmptyJSArray(
- ElementsKind elements_kind,
- PretenureFlag pretenure = NOT_TENURED) {
- return AllocateJSArrayAndStorage(elements_kind, 0, 0,
- DONT_INITIALIZE_ARRAY_ELEMENTS,
- pretenure);
- }
-
- // Allocate a JSArray with a specified length but elements that are left
- // uninitialized.
- MUST_USE_RESULT MaybeObject* AllocateJSArrayAndStorage(
- ElementsKind elements_kind,
- int length,
- int capacity,
- ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS,
- PretenureFlag pretenure = NOT_TENURED);
-
- MUST_USE_RESULT MaybeObject* AllocateJSArrayStorage(
- JSArray* array,
- int length,
- int capacity,
- ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS);
-
- // Allocate a JSArray with no elements
- MUST_USE_RESULT MaybeObject* AllocateJSArrayWithElements(
- FixedArrayBase* array_base,
- ElementsKind elements_kind,
- int length,
- PretenureFlag pretenure = NOT_TENURED);
-
// Returns a deep copy of the JavaScript object.
// Properties and elements are copied too.
- // Returns failure if allocation failed.
// Optionally takes an AllocationSite to be appended in an AllocationMemento.
- MUST_USE_RESULT MaybeObject* CopyJSObject(JSObject* source,
- AllocationSite* site = NULL);
-
- // Allocates a JS ArrayBuffer object.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateJSArrayBuffer();
-
- // Allocates a Harmony proxy or function proxy.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateJSProxy(Object* handler,
- Object* prototype);
-
- MUST_USE_RESULT MaybeObject* AllocateJSFunctionProxy(Object* handler,
- Object* call_trap,
- Object* construct_trap,
- Object* prototype);
-
- // Reinitialize a JSReceiver into an (empty) JS object of respective type and
- // size, but keeping the original prototype. The receiver must have at least
- // the size of the new object. The object is reinitialized and behaves as an
- // object that has been freshly allocated.
- // Returns failure if an error occured, otherwise object.
- MUST_USE_RESULT MaybeObject* ReinitializeJSReceiver(JSReceiver* object,
- InstanceType type,
- int size);
-
- // Reinitialize an JSGlobalProxy based on a constructor. The object
- // must have the same size as objects allocated using the
- // constructor. The object is reinitialized and behaves as an
- // object that has been freshly allocated using the constructor.
- MUST_USE_RESULT MaybeObject* ReinitializeJSGlobalProxy(
- JSFunction* constructor, JSGlobalProxy* global);
-
- // Allocates and initializes a new JavaScript object based on a map.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Passing an allocation site means that a memento will be created that
- // points to the site.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateJSObjectFromMap(
- Map* map,
- PretenureFlag pretenure = NOT_TENURED,
- bool alloc_props = true,
- AllocationSite* allocation_site = NULL);
-
- // Allocates a heap object based on the map.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this function does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* Allocate(Map* map, AllocationSpace space,
- AllocationSite* allocation_site = NULL);
-
- // Allocates a JS Map in the heap.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this function does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateMap(
- InstanceType instance_type,
- int instance_size,
- ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND);
-
- // Allocates a partial map for bootstrapping.
- MUST_USE_RESULT MaybeObject* AllocatePartialMap(InstanceType instance_type,
- int instance_size);
-
- // Allocates an empty code cache.
- MUST_USE_RESULT MaybeObject* AllocateCodeCache();
-
- // Allocates a serialized scope info.
- MUST_USE_RESULT MaybeObject* AllocateScopeInfo(int length);
-
- // Allocates an External object for v8's external API.
- MUST_USE_RESULT MaybeObject* AllocateExternal(void* value);
-
- // Allocates an empty PolymorphicCodeCache.
- MUST_USE_RESULT MaybeObject* AllocatePolymorphicCodeCache();
-
- // Allocates a pre-tenured empty AccessorPair.
- MUST_USE_RESULT MaybeObject* AllocateAccessorPair();
-
- // Allocates an empty TypeFeedbackInfo.
- MUST_USE_RESULT MaybeObject* AllocateTypeFeedbackInfo();
-
- // Allocates an AliasedArgumentsEntry.
- MUST_USE_RESULT MaybeObject* AllocateAliasedArgumentsEntry(int slot);
+ MUST_USE_RESULT AllocationResult CopyJSObject(JSObject* source,
+ AllocationSite* site = NULL);
// Clear the Instanceof cache (used when a prototype changes).
inline void ClearInstanceofCache();
@@ -843,257 +697,13 @@ class Heap {
// For use during bootup.
void RepairFreeListsAfterBoot();
- // Allocates and fully initializes a String. There are two String
- // encodings: ASCII and two byte. One should choose between the three string
- // allocation functions based on the encoding of the string buffer used to
- // initialized the string.
- // - ...FromAscii initializes the string from a buffer that is ASCII
- // encoded (it does not check that the buffer is ASCII encoded) and the
- // result will be ASCII encoded.
- // - ...FromUTF8 initializes the string from a buffer that is UTF-8
- // encoded. If the characters are all single-byte characters, the
- // result will be ASCII encoded, otherwise it will converted to two
- // byte.
- // - ...FromTwoByte initializes the string from a buffer that is two-byte
- // encoded. If the characters are all single-byte characters, the
- // result will be converted to ASCII, otherwise it will be left as
- // two-byte.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateStringFromOneByte(
- Vector<const uint8_t> str,
- PretenureFlag pretenure = NOT_TENURED);
- // TODO(dcarney): remove this function.
- MUST_USE_RESULT inline MaybeObject* AllocateStringFromOneByte(
- Vector<const char> str,
- PretenureFlag pretenure = NOT_TENURED) {
- return AllocateStringFromOneByte(Vector<const uint8_t>::cast(str),
- pretenure);
- }
- MUST_USE_RESULT inline MaybeObject* AllocateStringFromUtf8(
- Vector<const char> str,
- PretenureFlag pretenure = NOT_TENURED);
- MUST_USE_RESULT MaybeObject* AllocateStringFromUtf8Slow(
- Vector<const char> str,
- int non_ascii_start,
- PretenureFlag pretenure = NOT_TENURED);
- MUST_USE_RESULT MaybeObject* AllocateStringFromTwoByte(
- Vector<const uc16> str,
- PretenureFlag pretenure = NOT_TENURED);
-
- // Allocates an internalized string in old space based on the character
- // stream. Returns Failure::RetryAfterGC(requested_bytes, space) if the
- // allocation failed.
- // Please note this function does not perform a garbage collection.
- MUST_USE_RESULT inline MaybeObject* AllocateInternalizedStringFromUtf8(
- Vector<const char> str,
- int chars,
- uint32_t hash_field);
-
- MUST_USE_RESULT inline MaybeObject* AllocateOneByteInternalizedString(
- Vector<const uint8_t> str,
- uint32_t hash_field);
-
- MUST_USE_RESULT inline MaybeObject* AllocateTwoByteInternalizedString(
- Vector<const uc16> str,
- uint32_t hash_field);
-
template<typename T>
static inline bool IsOneByte(T t, int chars);
- template<typename T>
- MUST_USE_RESULT inline MaybeObject* AllocateInternalizedStringImpl(
- T t, int chars, uint32_t hash_field);
-
- template<bool is_one_byte, typename T>
- MUST_USE_RESULT MaybeObject* AllocateInternalizedStringImpl(
- T t, int chars, uint32_t hash_field);
-
- // Allocates and partially initializes a String. There are two String
- // encodings: ASCII and two byte. These functions allocate a string of the
- // given length and set its map and length fields. The characters of the
- // string are uninitialized.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateRawOneByteString(
- int length,
- PretenureFlag pretenure = NOT_TENURED);
- MUST_USE_RESULT MaybeObject* AllocateRawTwoByteString(
- int length,
- PretenureFlag pretenure = NOT_TENURED);
-
- // Computes a single character string where the character has code.
- // A cache is used for ASCII codes.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed. Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* LookupSingleCharacterStringFromCode(
- uint16_t code);
-
- // Allocate a byte array of the specified length
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateByteArray(
- int length,
- PretenureFlag pretenure = NOT_TENURED);
-
- // Allocates an external array of the specified length and type.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateExternalArray(
- int length,
- ExternalArrayType array_type,
- void* external_pointer,
- PretenureFlag pretenure);
-
- // Allocates a fixed typed array of the specified length and type.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateFixedTypedArray(
- int length,
- ExternalArrayType array_type,
- PretenureFlag pretenure);
-
- // Allocate a symbol in old space.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateSymbol();
- MUST_USE_RESULT MaybeObject* AllocatePrivateSymbol();
-
- // Allocate a tenured AllocationSite. It's payload is null
- MUST_USE_RESULT MaybeObject* AllocateAllocationSite();
-
- // Allocates a fixed array initialized with undefined values
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateFixedArray(
- int length,
- PretenureFlag pretenure = NOT_TENURED);
-
- // Allocates an uninitialized fixed array. It must be filled by the caller.
- //
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateUninitializedFixedArray(int length);
-
// Move len elements within a given array from src_index index to dst_index
// index.
void MoveElements(FixedArray* array, int dst_index, int src_index, int len);
- // Make a copy of src and return it. Returns
- // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
- MUST_USE_RESULT inline MaybeObject* CopyFixedArray(FixedArray* src);
-
- // Make a copy of src and return it. Returns
- // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
- MUST_USE_RESULT MaybeObject* CopyAndTenureFixedCOWArray(FixedArray* src);
-
- // Make a copy of src, set the map, and return the copy. Returns
- // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
- MUST_USE_RESULT MaybeObject* CopyFixedArrayWithMap(FixedArray* src, Map* map);
-
- // Make a copy of src and return it. Returns
- // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
- MUST_USE_RESULT inline MaybeObject* CopyFixedDoubleArray(
- FixedDoubleArray* src);
-
- // Make a copy of src, set the map, and return the copy. Returns
- // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
- MUST_USE_RESULT MaybeObject* CopyFixedDoubleArrayWithMap(
- FixedDoubleArray* src, Map* map);
-
- // Make a copy of src and return it. Returns
- // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
- MUST_USE_RESULT inline MaybeObject* CopyConstantPoolArray(
- ConstantPoolArray* src);
-
- // Make a copy of src, set the map, and return the copy. Returns
- // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
- MUST_USE_RESULT MaybeObject* CopyConstantPoolArrayWithMap(
- ConstantPoolArray* src, Map* map);
-
- // Allocates a fixed array initialized with the hole values.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateFixedArrayWithHoles(
- int length,
- PretenureFlag pretenure = NOT_TENURED);
-
- MUST_USE_RESULT MaybeObject* AllocateConstantPoolArray(
- int number_of_int64_entries,
- int number_of_code_ptr_entries,
- int number_of_heap_ptr_entries,
- int number_of_int32_entries);
-
- // Allocates a fixed double array with uninitialized values. Returns
- // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateUninitializedFixedDoubleArray(
- int length,
- PretenureFlag pretenure = NOT_TENURED);
-
- // Allocates a fixed double array with hole values. Returns
- // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateFixedDoubleArrayWithHoles(
- int length,
- PretenureFlag pretenure = NOT_TENURED);
-
- // AllocateHashTable is identical to AllocateFixedArray except
- // that the resulting object has hash_table_map as map.
- MUST_USE_RESULT MaybeObject* AllocateHashTable(
- int length, PretenureFlag pretenure = NOT_TENURED);
-
- // Allocate a native (but otherwise uninitialized) context.
- MUST_USE_RESULT MaybeObject* AllocateNativeContext();
-
- // Allocate a global context.
- MUST_USE_RESULT MaybeObject* AllocateGlobalContext(JSFunction* function,
- ScopeInfo* scope_info);
-
- // Allocate a module context.
- MUST_USE_RESULT MaybeObject* AllocateModuleContext(ScopeInfo* scope_info);
-
- // Allocate a function context.
- MUST_USE_RESULT MaybeObject* AllocateFunctionContext(int length,
- JSFunction* function);
-
- // Allocate a catch context.
- MUST_USE_RESULT MaybeObject* AllocateCatchContext(JSFunction* function,
- Context* previous,
- String* name,
- Object* thrown_object);
- // Allocate a 'with' context.
- MUST_USE_RESULT MaybeObject* AllocateWithContext(JSFunction* function,
- Context* previous,
- JSReceiver* extension);
-
- // Allocate a block context.
- MUST_USE_RESULT MaybeObject* AllocateBlockContext(JSFunction* function,
- Context* previous,
- ScopeInfo* info);
-
- // Allocates a new utility object in the old generation.
- MUST_USE_RESULT MaybeObject* AllocateStruct(InstanceType type);
-
- // Allocates a function initialized with a shared part.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateFunction(
- Map* function_map,
- SharedFunctionInfo* shared,
- Object* prototype,
- PretenureFlag pretenure = TENURED);
-
// Sloppy mode arguments object size.
static const int kSloppyArgumentsObjectSize =
JSObject::kHeaderSize + 2 * kPointerSize;
@@ -1105,84 +715,10 @@ class Heap {
// callee is only valid in sloppy mode.
static const int kArgumentsCalleeIndex = 1;
- // Allocates an arguments object - optionally with an elements array.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateArgumentsObject(
- Object* callee, int length);
-
- // Same as NewNumberFromDouble, but may return a preallocated/immutable
- // number object (e.g., minus_zero_value_, nan_value_)
- MUST_USE_RESULT MaybeObject* NumberFromDouble(
- double value, PretenureFlag pretenure = NOT_TENURED);
-
- // Allocated a HeapNumber from value.
- MUST_USE_RESULT MaybeObject* AllocateHeapNumber(
- double value, PretenureFlag pretenure = NOT_TENURED);
-
- // Converts an int into either a Smi or a HeapNumber object.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT inline MaybeObject* NumberFromInt32(
- int32_t value, PretenureFlag pretenure = NOT_TENURED);
-
- // Converts an int into either a Smi or a HeapNumber object.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT inline MaybeObject* NumberFromUint32(
- uint32_t value, PretenureFlag pretenure = NOT_TENURED);
-
- // Allocates a new foreign object.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateForeign(
- Address address, PretenureFlag pretenure = NOT_TENURED);
-
- // Allocates a new SharedFunctionInfo object.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateSharedFunctionInfo(Object* name);
-
- // Allocates a new JSMessageObject object.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note that this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateJSMessageObject(
- String* type,
- JSArray* arguments,
- int start_position,
- int end_position,
- Object* script,
- Object* stack_frames);
-
- // Allocate a new external string object, which is backed by a string
- // resource that resides outside the V8 heap.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateExternalStringFromAscii(
- const ExternalAsciiString::Resource* resource);
- MUST_USE_RESULT MaybeObject* AllocateExternalStringFromTwoByte(
- const ExternalTwoByteString::Resource* resource);
-
// Finalizes an external string by deleting the associated external
// data and clearing the resource pointer.
inline void FinalizeExternalString(String* string);
- // Allocates an uninitialized object. The memory is non-executable if the
- // hardware and OS allow.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this function does not perform a garbage collection.
- MUST_USE_RESULT inline MaybeObject* AllocateRaw(int size_in_bytes,
- AllocationSpace space,
- AllocationSpace retry_space);
-
// Initialize a filler object to keep the ability to iterate over the heap
// when shortening objects.
void CreateFillerObjectAt(Address addr, int size);
@@ -1194,55 +730,6 @@ class Heap {
// Maintain marking consistency for IncrementalMarking.
void AdjustLiveBytes(Address address, int by, InvocationMode mode);
- // Makes a new native code object
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed. On success, the pointer to the Code object is stored in the
- // self_reference. This allows generated code to reference its own Code
- // object by containing this pointer.
- // Please note this function does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* CreateCode(
- const CodeDesc& desc,
- Code::Flags flags,
- Handle<Object> self_reference,
- bool immovable = false,
- bool crankshafted = false,
- int prologue_offset = Code::kPrologueOffsetNotSet);
-
- MUST_USE_RESULT MaybeObject* CopyCode(Code* code);
-
- // Copy the code and scope info part of the code object, but insert
- // the provided data as the relocation information.
- MUST_USE_RESULT MaybeObject* CopyCode(Code* code, Vector<byte> reloc_info);
-
- // Finds the internalized copy for string in the string table.
- // If not found, a new string is added to the table and returned.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if allocation
- // failed.
- // Please note this function does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* InternalizeUtf8String(const char* str) {
- return InternalizeUtf8String(CStrVector(str));
- }
- MUST_USE_RESULT MaybeObject* InternalizeUtf8String(Vector<const char> str);
-
- MUST_USE_RESULT MaybeObject* InternalizeString(String* str);
- MUST_USE_RESULT MaybeObject* InternalizeStringWithKey(HashTableKey* key);
-
- bool InternalizeStringIfExists(String* str, String** result);
- bool InternalizeTwoCharsStringIfExists(String* str, String** result);
-
- // Compute the matching internalized string map for a string if possible.
- // NULL is returned if string is in new space or not flattened.
- Map* InternalizedStringMapForString(String* str);
-
- // Tries to flatten a string before compare operation.
- //
- // Returns a failure in case it was decided that flattening was
- // necessary and failed. Note, if flattening is not necessary the
- // string might stay non-flat even when not a failure is returned.
- //
- // Please note this function does not perform a garbage collection.
- MUST_USE_RESULT inline MaybeObject* PrepareForCompare(String* str);
-
// Converts the given boolean condition to JavaScript boolean value.
inline Object* ToBoolean(bool condition);
@@ -1301,11 +788,6 @@ class Heap {
PromotionQueue* promotion_queue() { return &promotion_queue_; }
-#ifdef DEBUG
- // Utility used with flag gc-greedy.
- void GarbageCollectionGreedyCheck();
-#endif
-
void AddGCPrologueCallback(v8::Isolate::GCPrologueCallback callback,
GCType gc_type_filter,
bool pass_isolate = true);
@@ -1531,6 +1013,10 @@ class Heap {
RECORD_SCRATCHPAD_SLOT
};
+ // If an object has an AllocationMemento trailing it, return it, otherwise
+ // return NULL;
+ inline AllocationMemento* FindAllocationMemento(HeapObject* object);
+
// An object may have an AllocationSite associated with it through a trailing
// AllocationMemento. Its feedback should be updated when objects are found
// in the heap.
@@ -1545,14 +1031,7 @@ class Heap {
// Support for the API.
//
- bool CreateApiObjects();
-
- // Attempt to find the number in a small cache. If we finds it, return
- // the string representation of the number. Otherwise return undefined.
- Object* GetNumberStringCache(Object* number);
-
- // Update the cache with a new number-string pair.
- void SetNumberStringCache(Object* number, String* str);
+ void CreateApiObjects();
// Adjusts the amount of registered external memory.
// Returns the adjusted value.
@@ -1593,11 +1072,31 @@ class Heap {
static const intptr_t kMinimumOldGenerationAllocationLimit =
8 * (Page::kPageSize > MB ? Page::kPageSize : MB);
+ static const int kLumpOfMemory = (i::kPointerSize / 4) * i::MB;
+
+ // The new space size has to be a power of 2.
+ static const int kMaxNewSpaceSizeLowMemoryDevice = 2 * kLumpOfMemory;
+ static const int kMaxNewSpaceSizeMediumMemoryDevice = 8 * kLumpOfMemory;
+ static const int kMaxNewSpaceSizeHighMemoryDevice = 16 * kLumpOfMemory;
+ static const int kMaxNewSpaceSizeHugeMemoryDevice = 16 * kLumpOfMemory;
+
+ // The old space size has to be a multiple of Page::kPageSize.
+ static const int kMaxOldSpaceSizeLowMemoryDevice = 128 * kLumpOfMemory;
+ static const int kMaxOldSpaceSizeMediumMemoryDevice = 256 * kLumpOfMemory;
+ static const int kMaxOldSpaceSizeHighMemoryDevice = 512 * kLumpOfMemory;
+ static const int kMaxOldSpaceSizeHugeMemoryDevice = 700 * kLumpOfMemory;
+
+ // The executable size has to be a multiple of Page::kPageSize.
+ static const int kMaxExecutableSizeLowMemoryDevice = 128 * kLumpOfMemory;
+ static const int kMaxExecutableSizeMediumMemoryDevice = 256 * kLumpOfMemory;
+ static const int kMaxExecutableSizeHighMemoryDevice = 512 * kLumpOfMemory;
+ static const int kMaxExecutableSizeHugeMemoryDevice = 700 * kLumpOfMemory;
+
intptr_t OldGenerationAllocationLimit(intptr_t old_gen_size) {
- const int divisor = FLAG_stress_compaction ? 10 : 1;
- intptr_t limit =
- Max(old_gen_size + old_gen_size / divisor,
- kMinimumOldGenerationAllocationLimit);
+ intptr_t limit = FLAG_stress_compaction
+ ? old_gen_size + old_gen_size / 10
+ : old_gen_size * old_space_growing_factor_;
+ limit = Max(limit, kMinimumOldGenerationAllocationLimit);
limit += new_space_.Capacity();
intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2;
return Min(limit, halfway_to_the_max);
@@ -1651,11 +1150,6 @@ class Heap {
// Generated code can treat direct references to this root as constant.
bool RootCanBeTreatedAsConstant(RootListIndex root_index);
- MUST_USE_RESULT MaybeObject* NumberToString(
- Object* number, bool check_number_string_cache = true);
- MUST_USE_RESULT MaybeObject* Uint32ToString(
- uint32_t value, bool check_number_string_cache = true);
-
Map* MapForFixedTypedArray(ExternalArrayType array_type);
RootListIndex RootIndexForFixedTypedArray(
ExternalArrayType array_type);
@@ -1782,20 +1276,6 @@ class Heap {
return &incremental_marking_;
}
- bool IsSweepingComplete() {
- return !mark_compact_collector()->IsConcurrentSweepingInProgress() &&
- old_data_space()->IsLazySweepingComplete() &&
- old_pointer_space()->IsLazySweepingComplete();
- }
-
- bool AdvanceSweepers(int step_size);
-
- bool EnsureSweepersProgressed(int step_size) {
- bool sweeping_complete = old_data_space()->EnsureSweeperProgress(step_size);
- sweeping_complete &= old_pointer_space()->EnsureSweeperProgress(step_size);
- return sweeping_complete;
- }
-
ExternalStringTable* external_string_table() {
return &external_string_table_;
}
@@ -1932,9 +1412,10 @@ class Heap {
Heap* heap_;
};
- MaybeObject* AddWeakObjectToCodeDependency(Object* obj, DependentCode* dep);
+ void AddWeakObjectToCodeDependency(Handle<Object> obj,
+ Handle<DependentCode> dep);
- DependentCode* LookupWeakObjectToCodeDependency(Object* obj);
+ DependentCode* LookupWeakObjectToCodeDependency(Handle<Object> obj);
void InitializeWeakObjectToCodeTable() {
set_weak_object_to_code_table(undefined_value());
@@ -1945,6 +1426,58 @@ class Heap {
static void FatalProcessOutOfMemory(const char* location,
bool take_snapshot = false);
+ protected:
+ // Methods made available to tests.
+
+ // Allocates a JS Map in the heap.
+ MUST_USE_RESULT AllocationResult AllocateMap(
+ InstanceType instance_type,
+ int instance_size,
+ ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND);
+
+ // Allocates and initializes a new JavaScript object based on a
+ // constructor.
+ // If allocation_site is non-null, then a memento is emitted after the object
+ // that points to the site.
+ MUST_USE_RESULT AllocationResult AllocateJSObject(
+ JSFunction* constructor,
+ PretenureFlag pretenure = NOT_TENURED,
+ AllocationSite* allocation_site = NULL);
+
+ // Allocates and initializes a new JavaScript object based on a map.
+ // Passing an allocation site means that a memento will be created that
+ // points to the site.
+ MUST_USE_RESULT AllocationResult AllocateJSObjectFromMap(
+ Map* map,
+ PretenureFlag pretenure = NOT_TENURED,
+ bool alloc_props = true,
+ AllocationSite* allocation_site = NULL);
+
+ // Allocated a HeapNumber from value.
+ MUST_USE_RESULT AllocationResult AllocateHeapNumber(
+ double value, PretenureFlag pretenure = NOT_TENURED);
+
+ // Allocate a byte array of the specified length
+ MUST_USE_RESULT AllocationResult AllocateByteArray(
+ int length,
+ PretenureFlag pretenure = NOT_TENURED);
+
+ // Allocates an arguments object - optionally with an elements array.
+ MUST_USE_RESULT AllocationResult AllocateArgumentsObject(
+ Object* callee, int length);
+
+ // Copy the code and scope info part of the code object, but insert
+ // the provided data as the relocation information.
+ MUST_USE_RESULT AllocationResult CopyCode(Code* code,
+ Vector<byte> reloc_info);
+
+ MUST_USE_RESULT AllocationResult CopyCode(Code* code);
+
+ // Allocates a fixed array initialized with undefined values
+ MUST_USE_RESULT AllocationResult AllocateFixedArray(
+ int length,
+ PretenureFlag pretenure = NOT_TENURED);
+
private:
Heap();
@@ -1962,6 +1495,11 @@ class Heap {
intptr_t max_executable_size_;
intptr_t maximum_committed_;
+ // The old space growing factor is used in the old space heap growing
+ // strategy. The new old space size is the current old space size times
+ // old_space_growing_factor_.
+ int old_space_growing_factor_;
+
// For keeping track of how much data has survived
// scavenge since last new space expansion.
int survived_since_last_expansion_;
@@ -2188,17 +1726,25 @@ class Heap {
return (pretenure == TENURED) ? preferred_old_space : NEW_SPACE;
}
- // Allocate an uninitialized fixed array.
- MUST_USE_RESULT MaybeObject* AllocateRawFixedArray(
- int length, PretenureFlag pretenure);
+ // Allocate an uninitialized object. The memory is non-executable if the
+ // hardware and OS allow. This is the single choke-point for allocations
+ // performed by the runtime and should not be bypassed (to extend this to
+ // inlined allocations, use the Heap::DisableInlineAllocation() support).
+ MUST_USE_RESULT inline AllocationResult AllocateRaw(
+ int size_in_bytes,
+ AllocationSpace space,
+ AllocationSpace retry_space);
- // Allocate an uninitialized fixed double array.
- MUST_USE_RESULT MaybeObject* AllocateRawFixedDoubleArray(
- int length, PretenureFlag pretenure);
+ // Allocates a heap object based on the map.
+ MUST_USE_RESULT AllocationResult Allocate(
+ Map* map,
+ AllocationSpace space,
+ AllocationSite* allocation_site = NULL);
- // Allocate an initialized fixed array with the given filler value.
- MUST_USE_RESULT MaybeObject* AllocateFixedArrayWithFiller(
- int length, PretenureFlag pretenure, Object* filler);
+ // Allocates a partial map for bootstrapping.
+ MUST_USE_RESULT AllocationResult AllocatePartialMap(
+ InstanceType instance_type,
+ int instance_size);
// Initializes a JSObject based on its map.
void InitializeJSObjectFromMap(JSObject* obj,
@@ -2207,8 +1753,147 @@ class Heap {
void InitializeAllocationMemento(AllocationMemento* memento,
AllocationSite* allocation_site);
+ // Allocate a block of memory in the given space (filled with a filler).
+ // Used as a fall-back for generated code when the space is full.
+ MUST_USE_RESULT AllocationResult AllocateFillerObject(int size,
+ bool double_align,
+ AllocationSpace space);
+
+ // Allocate an uninitialized fixed array.
+ MUST_USE_RESULT AllocationResult AllocateRawFixedArray(
+ int length, PretenureFlag pretenure);
+
+ // Allocate an uninitialized fixed double array.
+ MUST_USE_RESULT AllocationResult AllocateRawFixedDoubleArray(
+ int length, PretenureFlag pretenure);
+
+ // Allocate an initialized fixed array with the given filler value.
+ MUST_USE_RESULT AllocationResult AllocateFixedArrayWithFiller(
+ int length, PretenureFlag pretenure, Object* filler);
+
+ // Allocate and partially initializes a String. There are two String
+ // encodings: ASCII and two byte. These functions allocate a string of the
+ // given length and set its map and length fields. The characters of the
+ // string are uninitialized.
+ MUST_USE_RESULT AllocationResult AllocateRawOneByteString(
+ int length, PretenureFlag pretenure);
+ MUST_USE_RESULT AllocationResult AllocateRawTwoByteString(
+ int length, PretenureFlag pretenure);
+
+ // Allocates and fully initializes a String. There are two String
+ // encodings: ASCII and two byte. One should choose between the three string
+ // allocation functions based on the encoding of the string buffer used to
+ // initialized the string.
+ // - ...FromAscii initializes the string from a buffer that is ASCII
+ // encoded (it does not check that the buffer is ASCII encoded) and the
+ // result will be ASCII encoded.
+ // - ...FromUTF8 initializes the string from a buffer that is UTF-8
+ // encoded. If the characters are all single-byte characters, the
+ // result will be ASCII encoded, otherwise it will converted to two
+ // byte.
+ // - ...FromTwoByte initializes the string from a buffer that is two-byte
+ // encoded. If the characters are all single-byte characters, the
+ // result will be converted to ASCII, otherwise it will be left as
+ // two-byte.
+ MUST_USE_RESULT AllocationResult AllocateStringFromUtf8Slow(
+ Vector<const char> str,
+ int non_ascii_start,
+ PretenureFlag pretenure = NOT_TENURED);
+ MUST_USE_RESULT AllocationResult AllocateStringFromTwoByte(
+ Vector<const uc16> str,
+ PretenureFlag pretenure = NOT_TENURED);
+
bool CreateInitialMaps();
- bool CreateInitialObjects();
+ void CreateInitialObjects();
+
+ // Allocates an internalized string in old space based on the character
+ // stream.
+ MUST_USE_RESULT inline AllocationResult AllocateInternalizedStringFromUtf8(
+ Vector<const char> str,
+ int chars,
+ uint32_t hash_field);
+
+ MUST_USE_RESULT inline AllocationResult AllocateOneByteInternalizedString(
+ Vector<const uint8_t> str,
+ uint32_t hash_field);
+
+ MUST_USE_RESULT inline AllocationResult AllocateTwoByteInternalizedString(
+ Vector<const uc16> str,
+ uint32_t hash_field);
+
+ template<bool is_one_byte, typename T>
+ MUST_USE_RESULT AllocationResult AllocateInternalizedStringImpl(
+ T t, int chars, uint32_t hash_field);
+
+ template<typename T>
+ MUST_USE_RESULT inline AllocationResult AllocateInternalizedStringImpl(
+ T t, int chars, uint32_t hash_field);
+
+ // Allocates an uninitialized fixed array. It must be filled by the caller.
+ MUST_USE_RESULT AllocationResult AllocateUninitializedFixedArray(int length);
+
+ // Make a copy of src and return it. Returns
+ // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
+ MUST_USE_RESULT inline AllocationResult CopyFixedArray(FixedArray* src);
+
+ // Make a copy of src, set the map, and return the copy. Returns
+ // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
+ MUST_USE_RESULT AllocationResult CopyFixedArrayWithMap(FixedArray* src,
+ Map* map);
+
+ // Make a copy of src and return it. Returns
+ // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
+ MUST_USE_RESULT inline AllocationResult CopyFixedDoubleArray(
+ FixedDoubleArray* src);
+
+ // Make a copy of src and return it. Returns
+ // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
+ MUST_USE_RESULT inline AllocationResult CopyConstantPoolArray(
+ ConstantPoolArray* src);
+
+
+ // Computes a single character string where the character has code.
+ // A cache is used for ASCII codes.
+ MUST_USE_RESULT AllocationResult LookupSingleCharacterStringFromCode(
+ uint16_t code);
+
+ // Allocate a symbol in old space.
+ MUST_USE_RESULT AllocationResult AllocateSymbol();
+
+ // Make a copy of src, set the map, and return the copy.
+ MUST_USE_RESULT AllocationResult CopyConstantPoolArrayWithMap(
+ ConstantPoolArray* src, Map* map);
+
+ MUST_USE_RESULT AllocationResult AllocateConstantPoolArray(
+ int number_of_int64_entries,
+ int number_of_code_ptr_entries,
+ int number_of_heap_ptr_entries,
+ int number_of_int32_entries);
+
+ // Allocates an external array of the specified length and type.
+ MUST_USE_RESULT AllocationResult AllocateExternalArray(
+ int length,
+ ExternalArrayType array_type,
+ void* external_pointer,
+ PretenureFlag pretenure);
+
+ // Allocates a fixed typed array of the specified length and type.
+ MUST_USE_RESULT AllocationResult AllocateFixedTypedArray(
+ int length,
+ ExternalArrayType array_type,
+ PretenureFlag pretenure);
+
+ // Make a copy of src and return it.
+ MUST_USE_RESULT AllocationResult CopyAndTenureFixedCOWArray(FixedArray* src);
+
+ // Make a copy of src, set the map, and return the copy.
+ MUST_USE_RESULT AllocationResult CopyFixedDoubleArrayWithMap(
+ FixedDoubleArray* src, Map* map);
+
+ // Allocates a fixed double array with uninitialized values. Returns
+ MUST_USE_RESULT AllocationResult AllocateUninitializedFixedDoubleArray(
+ int length,
+ PretenureFlag pretenure = NOT_TENURED);
// These five Create*EntryStub functions are here and forced to not be inlined
// because of a gcc-4.4 bug that assigns wrong vtable entries.
@@ -2217,41 +1902,39 @@ class Heap {
void CreateFixedStubs();
- MUST_USE_RESULT MaybeObject* CreateOddball(const char* to_string,
- Object* to_number,
- byte kind);
-
- // Allocate a JSArray with no elements
- MUST_USE_RESULT MaybeObject* AllocateJSArray(
- ElementsKind elements_kind,
- PretenureFlag pretenure = NOT_TENURED);
-
// Allocate empty fixed array.
- MUST_USE_RESULT MaybeObject* AllocateEmptyFixedArray();
+ MUST_USE_RESULT AllocationResult AllocateEmptyFixedArray();
// Allocate empty external array of given type.
- MUST_USE_RESULT MaybeObject* AllocateEmptyExternalArray(
+ MUST_USE_RESULT AllocationResult AllocateEmptyExternalArray(
ExternalArrayType array_type);
// Allocate empty fixed typed array of given type.
- MUST_USE_RESULT MaybeObject* AllocateEmptyFixedTypedArray(
+ MUST_USE_RESULT AllocationResult AllocateEmptyFixedTypedArray(
ExternalArrayType array_type);
- // Allocate empty fixed double array.
- MUST_USE_RESULT MaybeObject* AllocateEmptyFixedDoubleArray();
-
// Allocate empty constant pool array.
- MUST_USE_RESULT MaybeObject* AllocateEmptyConstantPoolArray();
+ MUST_USE_RESULT AllocationResult AllocateEmptyConstantPoolArray();
// Allocate a tenured simple cell.
- MUST_USE_RESULT MaybeObject* AllocateCell(Object* value);
+ MUST_USE_RESULT AllocationResult AllocateCell(Object* value);
// Allocate a tenured JS global property cell initialized with the hole.
- MUST_USE_RESULT MaybeObject* AllocatePropertyCell();
+ MUST_USE_RESULT AllocationResult AllocatePropertyCell();
+
+ // Allocates a new utility object in the old generation.
+ MUST_USE_RESULT AllocationResult AllocateStruct(InstanceType type);
+
+ // Allocates a new foreign object.
+ MUST_USE_RESULT AllocationResult AllocateForeign(
+ Address address, PretenureFlag pretenure = NOT_TENURED);
+
+ MUST_USE_RESULT AllocationResult AllocateCode(int object_size,
+ bool immovable);
- // Allocate Box.
- MUST_USE_RESULT MaybeObject* AllocateBox(Object* value,
- PretenureFlag pretenure);
+ MUST_USE_RESULT AllocationResult InternalizeStringWithKey(HashTableKey* key);
+
+ MUST_USE_RESULT AllocationResult InternalizeString(String* str);
// Performs a minor collection in new generation.
void Scavenge();
@@ -2303,34 +1986,16 @@ class Heap {
// Slow part of scavenge object.
static void ScavengeObjectSlow(HeapObject** p, HeapObject* object);
- // Initializes a function with a shared part and prototype.
- // Note: this code was factored out of AllocateFunction such that
- // other parts of the VM could use it. Specifically, a function that creates
- // instances of type JS_FUNCTION_TYPE benefit from the use of this function.
- // Please note this does not perform a garbage collection.
- inline void InitializeFunction(
- JSFunction* function,
- SharedFunctionInfo* shared,
- Object* prototype);
-
// Total RegExp code ever generated
double total_regexp_code_generated_;
GCTracer* tracer_;
- // Allocates a small number to string cache.
- MUST_USE_RESULT MaybeObject* AllocateInitialNumberStringCache();
// Creates and installs the full-sized number string cache.
- void AllocateFullSizeNumberStringCache();
- // Get the length of the number to string cache based on the max semispace
- // size.
int FullSizeNumberStringCacheLength();
// Flush the number to string cache.
void FlushNumberStringCache();
- // Allocates a fixed-size allocation sites scratchpad.
- MUST_USE_RESULT MaybeObject* AllocateAllocationSitesScratchpad();
-
// Sets used allocation sites entries to undefined.
void FlushAllocationSitesScratchpad();
@@ -2746,10 +2411,10 @@ class HeapIterator BASE_EMBEDDED {
class KeyedLookupCache {
public:
// Lookup field offset for (map, name). If absent, -1 is returned.
- int Lookup(Map* map, Name* name);
+ int Lookup(Handle<Map> map, Handle<Name> name);
// Update an element in the cache.
- void Update(Map* map, Name* name, int field_offset);
+ void Update(Handle<Map> map, Handle<Name> name, int field_offset);
// Clear the cache.
void Clear();
@@ -2774,7 +2439,7 @@ class KeyedLookupCache {
}
}
- static inline int Hash(Map* map, Name* name);
+ static inline int Hash(Handle<Map> map, Handle<Name> name);
// Get the address of the keys and field_offsets arrays. Used in
// generated code to perform cache lookups.
@@ -3019,10 +2684,10 @@ class RegExpResultsCache {
ResultsCacheType type);
// Attempt to add value_array to the cache specified by type. On success,
// value_array is turned into a COW-array.
- static void Enter(Heap* heap,
- String* key_string,
- Object* key_pattern,
- FixedArray* value_array,
+ static void Enter(Isolate* isolate,
+ Handle<String> key_string,
+ Handle<Object> key_pattern,
+ Handle<FixedArray> value_array,
ResultsCacheType type);
static void Clear(FixedArray* cache);
static const int kRegExpResultsCacheSize = 0x100;
diff --git a/deps/v8/src/hydrogen-alias-analysis.h b/deps/v8/src/hydrogen-alias-analysis.h
index 21a54625ff..10325d2ec6 100644
--- a/deps/v8/src/hydrogen-alias-analysis.h
+++ b/deps/v8/src/hydrogen-alias-analysis.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_ALIAS_ANALYSIS_H_
#define V8_HYDROGEN_ALIAS_ANALYSIS_H_
diff --git a/deps/v8/src/hydrogen-bce.cc b/deps/v8/src/hydrogen-bce.cc
index dd71078a23..1f3f449a0c 100644
--- a/deps/v8/src/hydrogen-bce.cc
+++ b/deps/v8/src/hydrogen-bce.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-bce.h"
diff --git a/deps/v8/src/hydrogen-bce.h b/deps/v8/src/hydrogen-bce.h
index c55dea7b7a..6e501701fe 100644
--- a/deps/v8/src/hydrogen-bce.h
+++ b/deps/v8/src/hydrogen-bce.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_BCE_H_
#define V8_HYDROGEN_BCE_H_
diff --git a/deps/v8/src/hydrogen-bch.cc b/deps/v8/src/hydrogen-bch.cc
index a0a0fee710..e889c196f3 100644
--- a/deps/v8/src/hydrogen-bch.cc
+++ b/deps/v8/src/hydrogen-bch.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-bch.h"
diff --git a/deps/v8/src/hydrogen-bch.h b/deps/v8/src/hydrogen-bch.h
index a22dacdd42..28d540157f 100644
--- a/deps/v8/src/hydrogen-bch.h
+++ b/deps/v8/src/hydrogen-bch.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_BCH_H_
#define V8_HYDROGEN_BCH_H_
diff --git a/deps/v8/src/hydrogen-canonicalize.cc b/deps/v8/src/hydrogen-canonicalize.cc
index d3f72e9339..77f4a55eb3 100644
--- a/deps/v8/src/hydrogen-canonicalize.cc
+++ b/deps/v8/src/hydrogen-canonicalize.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-canonicalize.h"
#include "hydrogen-redundant-phi.h"
diff --git a/deps/v8/src/hydrogen-canonicalize.h b/deps/v8/src/hydrogen-canonicalize.h
index d2b289bc21..a0737ed631 100644
--- a/deps/v8/src/hydrogen-canonicalize.h
+++ b/deps/v8/src/hydrogen-canonicalize.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_CANONICALIZE_H_
#define V8_HYDROGEN_CANONICALIZE_H_
diff --git a/deps/v8/src/hydrogen-check-elimination.cc b/deps/v8/src/hydrogen-check-elimination.cc
index 52a549299a..701d9654b5 100644
--- a/deps/v8/src/hydrogen-check-elimination.cc
+++ b/deps/v8/src/hydrogen-check-elimination.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-check-elimination.h"
#include "hydrogen-alias-analysis.h"
@@ -44,7 +21,7 @@
namespace v8 {
namespace internal {
-typedef UniqueSet<Map>* MapSet;
+typedef const UniqueSet<Map>* MapSet;
struct HCheckTableEntry {
HValue* object_; // The object being approximated. NULL => invalid entry.
@@ -57,7 +34,7 @@ struct HCheckTableEntry {
// set of known maps for each object.
class HCheckTable : public ZoneObject {
public:
- static const int kMaxTrackedObjects = 10;
+ static const int kMaxTrackedObjects = 16;
explicit HCheckTable(HCheckEliminationPhase* phase)
: phase_(phase),
@@ -72,10 +49,6 @@ class HCheckTable : public ZoneObject {
ReduceCheckMaps(HCheckMaps::cast(instr));
break;
}
- case HValue::kCheckValue: {
- ReduceCheckValue(HCheckValue::cast(instr));
- break;
- }
case HValue::kLoadNamedField: {
ReduceLoadNamedField(HLoadNamedField::cast(instr));
break;
@@ -97,17 +70,14 @@ class HCheckTable : public ZoneObject {
HTransitionElementsKind::cast(instr));
break;
}
- case HValue::kCheckMapValue: {
- ReduceCheckMapValue(HCheckMapValue::cast(instr));
- break;
- }
case HValue::kCheckHeapObject: {
ReduceCheckHeapObject(HCheckHeapObject::cast(instr));
break;
}
default: {
// If the instruction changes maps uncontrollably, drop everything.
- if (instr->CheckChangesFlag(kMaps) ||
+ if (instr->CheckChangesFlag(kElementsKind) ||
+ instr->CheckChangesFlag(kMaps) ||
instr->CheckChangesFlag(kOsrEntries)) {
Kill();
}
@@ -154,13 +124,13 @@ class HCheckTable : public ZoneObject {
private:
// Copy state to successor block.
HCheckTable* Copy(HBasicBlock* succ, HBasicBlock* from_block, Zone* zone) {
- HCheckTable* copy = new(phase_->zone()) HCheckTable(phase_);
+ HCheckTable* copy = new(zone) HCheckTable(phase_);
for (int i = 0; i < size_; i++) {
HCheckTableEntry* old_entry = &entries_[i];
ASSERT(old_entry->maps_->size() > 0);
HCheckTableEntry* new_entry = &copy->entries_[i];
new_entry->object_ = old_entry->object_;
- new_entry->maps_ = old_entry->maps_->Copy(phase_->zone());
+ new_entry->maps_ = old_entry->maps_;
// Keep the check if the existing check's block dominates the successor.
if (old_entry->check_ != NULL &&
old_entry->check_->block()->Dominates(succ)) {
@@ -186,7 +156,7 @@ class HCheckTable : public ZoneObject {
HCheckTableEntry* pred_entry = copy->Find(phi_operand);
if (pred_entry != NULL) {
// Create an entry for a phi in the table.
- copy->Insert(phi, NULL, pred_entry->maps_->Copy(phase_->zone()));
+ copy->Insert(phi, NULL, pred_entry->maps_);
}
}
}
@@ -206,15 +176,15 @@ class HCheckTable : public ZoneObject {
if (entry == NULL) {
copy->Insert(object, cmp, cmp->map());
} else {
- MapSet list = new(phase_->zone()) UniqueSet<Map>();
- list->Add(cmp->map(), phase_->zone());
- entry->maps_ = list;
+ entry->maps_ = new(zone) UniqueSet<Map>(cmp->map(), zone);
entry->check_ = cmp;
}
} else {
// Learn on the false branch of if(CompareMap(x)).
if (entry != NULL) {
- entry->maps_->Remove(cmp->map());
+ UniqueSet<Map>* maps = entry->maps_->Copy(zone);
+ maps->Remove(cmp->map());
+ entry->maps_ = maps;
}
}
learned = true;
@@ -228,14 +198,12 @@ class HCheckTable : public ZoneObject {
HCheckTableEntry* re = copy->Find(right);
if (le == NULL) {
if (re != NULL) {
- copy->Insert(left, NULL, re->maps_->Copy(zone));
+ copy->Insert(left, NULL, re->maps_);
}
} else if (re == NULL) {
- copy->Insert(right, NULL, le->maps_->Copy(zone));
+ copy->Insert(right, NULL, le->maps_);
} else {
- MapSet intersect = le->maps_->Intersect(re->maps_, zone);
- le->maps_ = intersect;
- re->maps_ = intersect->Copy(zone);
+ le->maps_ = re->maps_ = le->maps_->Intersect(re->maps_, zone);
}
learned = true;
}
@@ -281,7 +249,7 @@ class HCheckTable : public ZoneObject {
compact = true;
} else {
this_entry->maps_ =
- this_entry->maps_->Union(that_entry->maps_, phase_->zone());
+ this_entry->maps_->Union(that_entry->maps_, zone);
if (this_entry->check_ != that_entry->check_) {
this_entry->check_ = NULL;
}
@@ -305,7 +273,7 @@ class HCheckTable : public ZoneObject {
if (entry != NULL) {
// entry found;
MapSet a = entry->maps_;
- MapSet i = instr->map_set().Copy(phase_->zone());
+ const UniqueSet<Map>* i = instr->maps();
if (a->IsSubset(i)) {
// The first check is more strict; the second is redundant.
if (entry->check_ != NULL) {
@@ -324,7 +292,8 @@ class HCheckTable : public ZoneObject {
}
return;
}
- MapSet intersection = i->Intersect(a, phase_->zone());
+ HGraph* graph = instr->block()->graph();
+ MapSet intersection = i->Intersect(a, graph->zone());
if (intersection->size() == 0) {
// Intersection is empty; probably megamorphic, which is likely to
// deopt anyway, so just leave things as they are.
@@ -334,7 +303,6 @@ class HCheckTable : public ZoneObject {
entry->maps_ = intersection;
if (intersection->size() != i->size()) {
// Narrow set of maps in the second check maps instruction.
- HGraph* graph = instr->block()->graph();
if (entry->check_ != NULL &&
entry->check_->block() == instr->block() &&
entry->check_->IsCheckMaps()) {
@@ -344,7 +312,7 @@ class HCheckTable : public ZoneObject {
TRACE(("CheckMaps #%d at B%d narrowed\n", check->id(),
check->block()->block_id()));
// Update map set and ensure that the check is alive.
- check->set_map_set(intersection, graph->zone());
+ check->set_maps(intersection);
check->ClearFlag(HValue::kIsDead);
TRACE(("Replacing redundant CheckMaps #%d at B%d with #%d\n",
instr->id(), instr->block()->block_id(), entry->check_->id()));
@@ -352,7 +320,7 @@ class HCheckTable : public ZoneObject {
} else {
TRACE(("CheckMaps #%d at B%d narrowed\n", instr->id(),
instr->block()->block_id()));
- instr->set_map_set(intersection, graph->zone());
+ instr->set_maps(intersection);
entry->check_ = instr;
}
@@ -364,25 +332,21 @@ class HCheckTable : public ZoneObject {
}
} else {
// No entry; insert a new one.
- Insert(object, instr, instr->map_set().Copy(phase_->zone()));
- }
- }
-
- void ReduceCheckValue(HCheckValue* instr) {
- // Canonicalize HCheckValues; they might have their values load-eliminated.
- HValue* value = instr->Canonicalize();
- if (value == NULL) {
- instr->DeleteAndReplaceWith(instr->value());
- INC_STAT(removed_);
- } else if (value != instr) {
- instr->DeleteAndReplaceWith(value);
- INC_STAT(redundant_);
+ Insert(object, instr, instr->maps());
}
}
void ReduceLoadNamedField(HLoadNamedField* instr) {
// Reduce a load of the map field when it is known to be a constant.
- if (!IsMapAccess(instr->access())) return;
+ if (!instr->access().IsMap()) {
+ // Check if we introduce field maps here.
+ MapSet maps = instr->maps();
+ if (maps != NULL) {
+ ASSERT_NE(0, maps->size());
+ Insert(instr, NULL, maps);
+ }
+ return;
+ }
HValue* object = instr->object()->ActualValue();
MapSet maps = FindMaps(object);
@@ -395,41 +359,6 @@ class HCheckTable : public ZoneObject {
INC_STAT(loads_);
}
- void ReduceCheckMapValue(HCheckMapValue* instr) {
- if (!instr->map()->IsConstant()) return; // Nothing to learn.
-
- HValue* object = instr->value()->ActualValue();
- // Match a HCheckMapValue(object, HConstant(map))
- Unique<Map> map = MapConstant(instr->map());
-
- HCheckTableEntry* entry = Find(object);
- if (entry != NULL) {
- MapSet maps = entry->maps_;
- if (maps->Contains(map)) {
- if (maps->size() == 1) {
- // Object is known to have exactly this map.
- if (entry->check_ != NULL) {
- instr->DeleteAndReplaceWith(entry->check_);
- } else {
- // Mark check as dead but leave it in the graph as a checkpoint for
- // subsequent checks.
- instr->SetFlag(HValue::kIsDead);
- entry->check_ = instr;
- }
- INC_STAT(removed_);
- } else {
- // Only one map survives the check.
- maps->Clear();
- maps->Add(map, phase_->zone());
- entry->check_ = instr;
- }
- }
- } else {
- // No prior information.
- Insert(object, instr, map);
- }
- }
-
void ReduceCheckHeapObject(HCheckHeapObject* instr) {
if (FindMaps(instr->value()->ActualValue()) != NULL) {
// If the object has known maps, it's definitely a heap object.
@@ -443,12 +372,12 @@ class HCheckTable : public ZoneObject {
if (instr->has_transition()) {
// This store transitions the object to a new map.
Kill(object);
- Insert(object, NULL, MapConstant(instr->transition()));
- } else if (IsMapAccess(instr->access())) {
+ Insert(object, NULL, HConstant::cast(instr->transition())->MapValue());
+ } else if (instr->access().IsMap()) {
// This is a store directly to the map field of the object.
Kill(object);
if (!instr->value()->IsConstant()) return;
- Insert(object, NULL, MapConstant(instr->value()));
+ Insert(object, NULL, HConstant::cast(instr->value())->MapValue());
} else {
// If the instruction changes maps, it should be handled above.
CHECK(!instr->CheckChangesFlag(kMaps));
@@ -488,7 +417,7 @@ class HCheckTable : public ZoneObject {
if (maps_left == NULL) return;
MapSet maps_right = FindMaps(instr->right()->ActualValue());
if (maps_right == NULL) return;
- MapSet intersection = maps_left->Intersect(maps_right, phase_->zone());
+ MapSet intersection = maps_left->Intersect(maps_right, zone());
if (intersection->size() > 0) return;
TRACE(("Marking redundant CompareObjectEqAndBranch #%d at B%d as false\n",
@@ -501,13 +430,15 @@ class HCheckTable : public ZoneObject {
}
void ReduceTransitionElementsKind(HTransitionElementsKind* instr) {
- MapSet maps = FindMaps(instr->object()->ActualValue());
+ HCheckTableEntry* entry = Find(instr->object()->ActualValue());
// Can only learn more about an object that already has a known set of maps.
- if (maps == NULL) return;
- if (maps->Contains(instr->original_map())) {
+ if (entry == NULL) return;
+ if (entry->maps_->Contains(instr->original_map())) {
// If the object has the original map, it will be transitioned.
+ UniqueSet<Map>* maps = entry->maps_->Copy(zone());
maps->Remove(instr->original_map());
- maps->Add(instr->transitioned_map(), phase_->zone());
+ maps->Add(instr->transitioned_map(), zone());
+ entry->maps_ = maps;
} else {
// Object does not have the given map, thus the transition is redundant.
instr->DeleteAndReplaceWith(instr->object());
@@ -608,9 +539,7 @@ class HCheckTable : public ZoneObject {
}
void Insert(HValue* object, HInstruction* check, Unique<Map> map) {
- MapSet list = new(phase_->zone()) UniqueSet<Map>();
- list->Add(map, phase_->zone());
- Insert(object, check, list);
+ Insert(object, check, new(zone()) UniqueSet<Map>(map, zone()));
}
void Insert(HValue* object, HInstruction* check, MapSet maps) {
@@ -623,13 +552,7 @@ class HCheckTable : public ZoneObject {
if (size_ < kMaxTrackedObjects) size_++;
}
- bool IsMapAccess(HObjectAccess access) {
- return access.IsInobject() && access.offset() == JSObject::kMapOffset;
- }
-
- Unique<Map> MapConstant(HValue* value) {
- return Unique<Map>::cast(HConstant::cast(value)->GetUnique());
- }
+ Zone* zone() const { return phase_->zone(); }
friend class HCheckMapsEffects;
friend class HCheckEliminationPhase;
@@ -647,26 +570,28 @@ class HCheckTable : public ZoneObject {
class HCheckMapsEffects : public ZoneObject {
public:
explicit HCheckMapsEffects(Zone* zone)
- : maps_stored_(false),
- stores_(5, zone) { }
+ : objects_(0, zone), maps_stored_(false) {}
- inline bool Disabled() {
- return false; // Effects are _not_ disabled.
- }
+ // Effects are _not_ disabled.
+ inline bool Disabled() const { return false; }
// Process a possibly side-effecting instruction.
void Process(HInstruction* instr, Zone* zone) {
switch (instr->opcode()) {
case HValue::kStoreNamedField: {
- stores_.Add(HStoreNamedField::cast(instr), zone);
+ HStoreNamedField* store = HStoreNamedField::cast(instr);
+ if (store->access().IsMap() && store->has_transition()) {
+ objects_.Add(store->object(), zone);
+ }
break;
}
- case HValue::kOsrEntry: {
- // Kill everything. Loads must not be hoisted past the OSR entry.
- maps_stored_ = true;
+ case HValue::kTransitionElementsKind: {
+ objects_.Add(HTransitionElementsKind::cast(instr)->object(), zone);
+ break;
}
default: {
maps_stored_ |= (instr->CheckChangesFlag(kMaps) |
+ instr->CheckChangesFlag(kOsrEntries) |
instr->CheckChangesFlag(kElementsKind));
}
}
@@ -680,26 +605,23 @@ class HCheckMapsEffects : public ZoneObject {
return;
}
- // Kill maps for each store contained in these effects.
- for (int i = 0; i < stores_.length(); i++) {
- HStoreNamedField* s = stores_[i];
- if (table->IsMapAccess(s->access()) || s->has_transition()) {
- table->Kill(s->object()->ActualValue());
- }
+ // Kill maps for each object contained in these effects.
+ for (int i = 0; i < objects_.length(); ++i) {
+ table->Kill(objects_[i]->ActualValue());
}
}
// Union these effects with the other effects.
void Union(HCheckMapsEffects* that, Zone* zone) {
maps_stored_ |= that->maps_stored_;
- for (int i = 0; i < that->stores_.length(); i++) {
- stores_.Add(that->stores_[i], zone);
+ for (int i = 0; i < that->objects_.length(); ++i) {
+ objects_.Add(that->objects_[i], zone);
}
}
private:
+ ZoneList<HValue*> objects_;
bool maps_stored_ : 1;
- ZoneList<HStoreNamedField*> stores_;
};
diff --git a/deps/v8/src/hydrogen-check-elimination.h b/deps/v8/src/hydrogen-check-elimination.h
index b429b17462..b38447b1e7 100644
--- a/deps/v8/src/hydrogen-check-elimination.h
+++ b/deps/v8/src/hydrogen-check-elimination.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_CHECK_ELIMINATION_H_
#define V8_HYDROGEN_CHECK_ELIMINATION_H_
diff --git a/deps/v8/src/hydrogen-dce.cc b/deps/v8/src/hydrogen-dce.cc
index 3a2eac40e5..be551efa8b 100644
--- a/deps/v8/src/hydrogen-dce.cc
+++ b/deps/v8/src/hydrogen-dce.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-dce.h"
#include "v8.h"
diff --git a/deps/v8/src/hydrogen-dce.h b/deps/v8/src/hydrogen-dce.h
index 2d73b380e4..18cd755c95 100644
--- a/deps/v8/src/hydrogen-dce.h
+++ b/deps/v8/src/hydrogen-dce.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_DCE_H_
#define V8_HYDROGEN_DCE_H_
diff --git a/deps/v8/src/hydrogen-dehoist.cc b/deps/v8/src/hydrogen-dehoist.cc
index bdf2cfb258..44aeb4887d 100644
--- a/deps/v8/src/hydrogen-dehoist.cc
+++ b/deps/v8/src/hydrogen-dehoist.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-dehoist.h"
diff --git a/deps/v8/src/hydrogen-dehoist.h b/deps/v8/src/hydrogen-dehoist.h
index 140dc6e0e2..930e29bdc5 100644
--- a/deps/v8/src/hydrogen-dehoist.h
+++ b/deps/v8/src/hydrogen-dehoist.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_DEHOIST_H_
#define V8_HYDROGEN_DEHOIST_H_
diff --git a/deps/v8/src/hydrogen-environment-liveness.cc b/deps/v8/src/hydrogen-environment-liveness.cc
index d7501ac49e..2dd1233def 100644
--- a/deps/v8/src/hydrogen-environment-liveness.cc
+++ b/deps/v8/src/hydrogen-environment-liveness.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-environment-liveness.h"
@@ -84,8 +61,8 @@ void HEnvironmentLivenessAnalysisPhase::ZapEnvironmentSlotsInSuccessors(
}
HSimulate* simulate = first_simulate_.at(successor_id);
if (simulate == NULL) continue;
- ASSERT(simulate->closure().is_identical_to(
- block->last_environment()->closure()));
+ ASSERT(VerifyClosures(simulate->closure(),
+ block->last_environment()->closure()));
ZapEnvironmentSlot(i, simulate);
}
}
@@ -97,7 +74,7 @@ void HEnvironmentLivenessAnalysisPhase::ZapEnvironmentSlotsForInstruction(
if (!marker->CheckFlag(HValue::kEndsLiveRange)) return;
HSimulate* simulate = marker->next_simulate();
if (simulate != NULL) {
- ASSERT(simulate->closure().is_identical_to(marker->closure()));
+ ASSERT(VerifyClosures(simulate->closure(), marker->closure()));
ZapEnvironmentSlot(marker->index(), simulate);
}
}
@@ -241,4 +218,14 @@ void HEnvironmentLivenessAnalysisPhase::Run() {
}
}
+
+#ifdef DEBUG
+bool HEnvironmentLivenessAnalysisPhase::VerifyClosures(
+ Handle<JSFunction> a, Handle<JSFunction> b) {
+ Heap::RelocationLock for_heap_access(isolate()->heap());
+ AllowHandleDereference for_verification;
+ return a.is_identical_to(b);
+}
+#endif
+
} } // namespace v8::internal
diff --git a/deps/v8/src/hydrogen-environment-liveness.h b/deps/v8/src/hydrogen-environment-liveness.h
index 248ec5ce5d..c72cd0f337 100644
--- a/deps/v8/src/hydrogen-environment-liveness.h
+++ b/deps/v8/src/hydrogen-environment-liveness.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_ENVIRONMENT_LIVENESS_H_
#define V8_HYDROGEN_ENVIRONMENT_LIVENESS_H_
@@ -55,6 +32,9 @@ class HEnvironmentLivenessAnalysisPhase : public HPhase {
void ZapEnvironmentSlotsForInstruction(HEnvironmentMarker* marker);
void UpdateLivenessAtBlockEnd(HBasicBlock* block, BitVector* live);
void UpdateLivenessAtInstruction(HInstruction* instr, BitVector* live);
+#ifdef DEBUG
+ bool VerifyClosures(Handle<JSFunction> a, Handle<JSFunction> b);
+#endif
int block_count_;
diff --git a/deps/v8/src/hydrogen-escape-analysis.cc b/deps/v8/src/hydrogen-escape-analysis.cc
index 1023019923..8514d889f0 100644
--- a/deps/v8/src/hydrogen-escape-analysis.cc
+++ b/deps/v8/src/hydrogen-escape-analysis.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-escape-analysis.h"
@@ -155,12 +132,29 @@ HValue* HEscapeAnalysisPhase::NewMapCheckAndInsert(HCapturedObject* state,
// TODO(mstarzinger): This will narrow a map check against a set of maps
// down to the first element in the set. Revisit and fix this.
HCheckValue* check = HCheckValue::New(
- zone, NULL, value, mapcheck->first_map(), false);
+ zone, NULL, value, mapcheck->maps()->at(0), false);
check->InsertBefore(mapcheck);
return check;
}
+// Replace a field load with a given value, forcing Smi representation if
+// necessary.
+HValue* HEscapeAnalysisPhase::NewLoadReplacement(
+ HLoadNamedField* load, HValue* load_value) {
+ HValue* replacement = load_value;
+ Representation representation = load->representation();
+ if (representation.IsSmi()) {
+ Zone* zone = graph()->zone();
+ HInstruction* new_instr =
+ HForceRepresentation::New(zone, NULL, load_value, representation);
+ new_instr->InsertAfter(load);
+ replacement = new_instr;
+ }
+ return replacement;
+}
+
+
// Performs a forward data-flow analysis of all loads and stores on the
// given captured allocation. This uses a reverse post-order iteration
// over affected basic blocks. All non-escaping instructions are handled
@@ -196,10 +190,11 @@ void HEscapeAnalysisPhase::AnalyzeDataFlow(HInstruction* allocate) {
int index = load->access().offset() / kPointerSize;
if (load->object() != allocate) continue;
ASSERT(load->access().IsInobject());
- HValue* replacement = state->OperandAt(index);
+ HValue* replacement =
+ NewLoadReplacement(load, state->OperandAt(index));
load->DeleteAndReplaceWith(replacement);
if (FLAG_trace_escape_analysis) {
- PrintF("Replacing load #%d with #%d (%s)\n", instr->id(),
+ PrintF("Replacing load #%d with #%d (%s)\n", load->id(),
replacement->id(), replacement->Mnemonic());
}
break;
diff --git a/deps/v8/src/hydrogen-escape-analysis.h b/deps/v8/src/hydrogen-escape-analysis.h
index 3e27cc1b48..5ff0b32d3e 100644
--- a/deps/v8/src/hydrogen-escape-analysis.h
+++ b/deps/v8/src/hydrogen-escape-analysis.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_ESCAPE_ANALYSIS_H_
#define V8_HYDROGEN_ESCAPE_ANALYSIS_H_
@@ -62,6 +39,8 @@ class HEscapeAnalysisPhase : public HPhase {
HValue* NewMapCheckAndInsert(HCapturedObject* state, HCheckMaps* mapcheck);
+ HValue* NewLoadReplacement(HLoadNamedField* load, HValue* load_value);
+
HCapturedObject* StateAt(HBasicBlock* block) {
return block_states_.at(block->block_id());
}
diff --git a/deps/v8/src/hydrogen-flow-engine.h b/deps/v8/src/hydrogen-flow-engine.h
index 99a2f841a7..04902b297a 100644
--- a/deps/v8/src/hydrogen-flow-engine.h
+++ b/deps/v8/src/hydrogen-flow-engine.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_FLOW_ENGINE_H_
#define V8_HYDROGEN_FLOW_ENGINE_H_
diff --git a/deps/v8/src/hydrogen-gvn.cc b/deps/v8/src/hydrogen-gvn.cc
index 4c98015bee..f9d1b408a7 100644
--- a/deps/v8/src/hydrogen-gvn.cc
+++ b/deps/v8/src/hydrogen-gvn.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen.h"
#include "hydrogen-gvn.h"
diff --git a/deps/v8/src/hydrogen-gvn.h b/deps/v8/src/hydrogen-gvn.h
index d00dd05585..25a5c24da6 100644
--- a/deps/v8/src/hydrogen-gvn.h
+++ b/deps/v8/src/hydrogen-gvn.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_GVN_H_
#define V8_HYDROGEN_GVN_H_
diff --git a/deps/v8/src/hydrogen-infer-representation.cc b/deps/v8/src/hydrogen-infer-representation.cc
index f61649a68f..3e983476f3 100644
--- a/deps/v8/src/hydrogen-infer-representation.cc
+++ b/deps/v8/src/hydrogen-infer-representation.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-infer-representation.h"
diff --git a/deps/v8/src/hydrogen-infer-representation.h b/deps/v8/src/hydrogen-infer-representation.h
index 7c605696c4..a2c8466f93 100644
--- a/deps/v8/src/hydrogen-infer-representation.h
+++ b/deps/v8/src/hydrogen-infer-representation.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_INFER_REPRESENTATION_H_
#define V8_HYDROGEN_INFER_REPRESENTATION_H_
diff --git a/deps/v8/src/hydrogen-infer-types.cc b/deps/v8/src/hydrogen-infer-types.cc
index 01c6084736..7a3208b67f 100644
--- a/deps/v8/src/hydrogen-infer-types.cc
+++ b/deps/v8/src/hydrogen-infer-types.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-infer-types.h"
diff --git a/deps/v8/src/hydrogen-infer-types.h b/deps/v8/src/hydrogen-infer-types.h
index cfcbf3549b..d1abcdac5a 100644
--- a/deps/v8/src/hydrogen-infer-types.h
+++ b/deps/v8/src/hydrogen-infer-types.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_INFER_TYPES_H_
#define V8_HYDROGEN_INFER_TYPES_H_
diff --git a/deps/v8/src/hydrogen-instructions.cc b/deps/v8/src/hydrogen-instructions.cc
index 84dcb18248..f5c5c32f40 100644
--- a/deps/v8/src/hydrogen-instructions.cc
+++ b/deps/v8/src/hydrogen-instructions.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -509,6 +486,8 @@ bool HValue::CanReplaceWithDummyUses() {
!(block()->IsReachable() ||
IsBlockEntry() ||
IsControlInstruction() ||
+ IsArgumentsObject() ||
+ IsCapturedObject() ||
IsSimulate() ||
IsEnterInlined() ||
IsLeaveInlined());
@@ -588,17 +567,6 @@ void HValue::PrintTypeTo(StringStream* stream) {
}
-void HValue::PrintRangeTo(StringStream* stream) {
- if (range() == NULL || range()->IsMostGeneric()) return;
- // Note: The c1visualizer syntax for locals allows only a sequence of the
- // following characters: A-Za-z0-9_-|:
- stream->Add(" range:%d_%d%s",
- range()->lower(),
- range()->upper(),
- range()->CanBeMinusZero() ? "_m0" : "");
-}
-
-
void HValue::PrintChangesTo(StringStream* stream) {
GVNFlagSet changes_flags = ChangesFlags();
if (changes_flags.IsEmpty()) return;
@@ -699,7 +667,6 @@ void HSourcePosition::PrintTo(FILE* out) {
void HInstruction::PrintTo(StringStream* stream) {
PrintMnemonicTo(stream);
PrintDataTo(stream);
- PrintRangeTo(stream);
PrintChangesTo(stream);
PrintTypeTo(stream);
if (CheckFlag(HValue::kHasNoObservableSideEffects)) {
@@ -841,104 +808,133 @@ void HInstruction::Verify() {
#endif
-static bool HasPrimitiveRepresentation(HValue* instr) {
- return instr->representation().IsInteger32() ||
- instr->representation().IsDouble();
-}
-
-
bool HInstruction::CanDeoptimize() {
// TODO(titzer): make this a virtual method?
switch (opcode()) {
+ case HValue::kAbnormalExit:
case HValue::kAccessArgumentsAt:
- case HValue::kApplyArguments:
+ case HValue::kAllocate:
case HValue::kArgumentsElements:
case HValue::kArgumentsLength:
case HValue::kArgumentsObject:
+ case HValue::kBlockEntry:
case HValue::kBoundsCheckBaseIndexInformation:
+ case HValue::kCallFunction:
+ case HValue::kCallJSFunction:
+ case HValue::kCallNew:
+ case HValue::kCallNewArray:
+ case HValue::kCallStub:
+ case HValue::kCallWithDescriptor:
case HValue::kCapturedObject:
- case HValue::kClampToUint8:
+ case HValue::kClassOfTestAndBranch:
+ case HValue::kCompareGeneric:
+ case HValue::kCompareHoleAndBranch:
+ case HValue::kCompareMap:
+ case HValue::kCompareMinusZeroAndBranch:
+ case HValue::kCompareNumericAndBranch:
+ case HValue::kCompareObjectEqAndBranch:
case HValue::kConstant:
+ case HValue::kConstructDouble:
case HValue::kContext:
- case HValue::kDateField:
case HValue::kDebugBreak:
case HValue::kDeclareGlobals:
- case HValue::kDiv:
+ case HValue::kDoubleBits:
case HValue::kDummyUse:
case HValue::kEnterInlined:
case HValue::kEnvironmentMarker:
- case HValue::kForInCacheArray:
- case HValue::kForInPrepareMap:
- case HValue::kFunctionLiteral:
+ case HValue::kForceRepresentation:
case HValue::kGetCachedArrayIndex:
case HValue::kGoto:
+ case HValue::kHasCachedArrayIndexAndBranch:
+ case HValue::kHasInstanceTypeAndBranch:
case HValue::kInnerAllocatedObject:
case HValue::kInstanceOf:
case HValue::kInstanceOfKnownGlobal:
- case HValue::kInvokeFunction:
+ case HValue::kIsConstructCallAndBranch:
+ case HValue::kIsObjectAndBranch:
+ case HValue::kIsSmiAndBranch:
+ case HValue::kIsStringAndBranch:
+ case HValue::kIsUndetectableAndBranch:
case HValue::kLeaveInlined:
- case HValue::kLoadContextSlot:
case HValue::kLoadFieldByIndex:
- case HValue::kLoadFunctionPrototype:
- case HValue::kLoadGlobalCell:
case HValue::kLoadGlobalGeneric:
- case HValue::kLoadKeyed:
- case HValue::kLoadKeyedGeneric:
case HValue::kLoadNamedField:
case HValue::kLoadNamedGeneric:
case HValue::kLoadRoot:
case HValue::kMapEnumLength:
- case HValue::kMathFloorOfDiv:
case HValue::kMathMinMax:
- case HValue::kMod:
- case HValue::kMul:
- case HValue::kOsrEntry:
case HValue::kParameter:
- case HValue::kPower:
+ case HValue::kPhi:
case HValue::kPushArgument:
+ case HValue::kRegExpLiteral:
+ case HValue::kReturn:
case HValue::kRor:
case HValue::kSar:
case HValue::kSeqStringGetChar:
+ case HValue::kStoreCodeEntry:
+ case HValue::kStoreKeyed:
+ case HValue::kStoreNamedGeneric:
+ case HValue::kStringCharCodeAt:
+ case HValue::kStringCharFromCode:
+ case HValue::kThisFunction:
+ case HValue::kTypeofIsAndBranch:
+ case HValue::kUnknownOSRValue:
+ case HValue::kUseConst:
+ return false;
+
+ case HValue::kAdd:
+ case HValue::kApplyArguments:
+ case HValue::kBitwise:
+ case HValue::kBoundsCheck:
+ case HValue::kBranch:
+ case HValue::kCallRuntime:
+ case HValue::kChange:
+ case HValue::kCheckHeapObject:
+ case HValue::kCheckInstanceType:
+ case HValue::kCheckMapValue:
+ case HValue::kCheckMaps:
+ case HValue::kCheckSmi:
+ case HValue::kCheckValue:
+ case HValue::kClampToUint8:
+ case HValue::kDateField:
+ case HValue::kDeoptimize:
+ case HValue::kDiv:
+ case HValue::kForInCacheArray:
+ case HValue::kForInPrepareMap:
+ case HValue::kFunctionLiteral:
+ case HValue::kInvokeFunction:
+ case HValue::kLoadContextSlot:
+ case HValue::kLoadFunctionPrototype:
+ case HValue::kLoadGlobalCell:
+ case HValue::kLoadKeyed:
+ case HValue::kLoadKeyedGeneric:
+ case HValue::kMathFloorOfDiv:
+ case HValue::kMod:
+ case HValue::kMul:
+ case HValue::kOsrEntry:
+ case HValue::kPower:
case HValue::kSeqStringSetChar:
case HValue::kShl:
case HValue::kShr:
case HValue::kSimulate:
case HValue::kStackCheck:
- case HValue::kStoreCodeEntry:
case HValue::kStoreContextSlot:
case HValue::kStoreGlobalCell:
- case HValue::kStoreKeyed:
case HValue::kStoreKeyedGeneric:
case HValue::kStoreNamedField:
- case HValue::kStoreNamedGeneric:
case HValue::kStringAdd:
- case HValue::kStringCharCodeAt:
- case HValue::kStringCharFromCode:
+ case HValue::kStringCompareAndBranch:
case HValue::kSub:
- case HValue::kThisFunction:
case HValue::kToFastProperties:
case HValue::kTransitionElementsKind:
case HValue::kTrapAllocationMemento:
case HValue::kTypeof:
case HValue::kUnaryMathOperation:
- case HValue::kUseConst:
case HValue::kWrapReceiver:
- return false;
- case HValue::kForceRepresentation:
- case HValue::kAdd:
- case HValue::kBitwise:
- case HValue::kChange:
- case HValue::kCompareGeneric:
- // These instructions might deoptimize if they are not primitive.
- if (!HasPrimitiveRepresentation(this)) return true;
- for (int i = 0; i < OperandCount(); i++) {
- HValue* input = OperandAt(i);
- if (!HasPrimitiveRepresentation(input)) return true;
- }
- return false;
- default:
return true;
}
+ UNREACHABLE();
+ return true;
}
@@ -1228,6 +1224,13 @@ bool HBranch::KnownSuccessorBlock(HBasicBlock** block) {
}
+void HBranch::PrintDataTo(StringStream* stream) {
+ HUnaryControlInstruction::PrintDataTo(stream);
+ stream->Add(" ");
+ expected_input_types().Print(stream);
+}
+
+
void HCompareMap::PrintDataTo(StringStream* stream) {
value()->PrintNameTo(stream);
stream->Add(" (%p)", *map().handle());
@@ -1377,6 +1380,17 @@ void HCheckMapValue::PrintDataTo(StringStream* stream) {
}
+HValue* HCheckMapValue::Canonicalize() {
+ if (map()->IsConstant()) {
+ HConstant* c_map = HConstant::cast(map());
+ return HCheckMaps::CreateAndInsertAfter(
+ block()->graph()->zone(), value(), c_map->MapValue(),
+ c_map->HasStableMapValue(), this);
+ }
+ return this;
+}
+
+
void HForInPrepareMap::PrintDataTo(StringStream* stream) {
enumerable()->PrintNameTo(stream);
}
@@ -1561,6 +1575,7 @@ void HChange::PrintDataTo(StringStream* stream) {
HUnaryOperation::PrintDataTo(stream);
stream->Add(" %s to %s", from().Mnemonic(), to().Mnemonic());
+ if (CanTruncateToSmi()) stream->Add(" truncating-smi");
if (CanTruncateToInt32()) stream->Add(" truncating-int32");
if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?");
if (CheckFlag(kAllowUndefinedAsNaN)) stream->Add(" allow-undefined-as-nan");
@@ -1665,32 +1680,33 @@ void HCheckInstanceType::GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag) {
}
-bool HCheckMaps::HandleSideEffectDominator(GVNFlag side_effect,
- HValue* dominator) {
- ASSERT(side_effect == kMaps);
- // TODO(mstarzinger): For now we specialize on HStoreNamedField, but once
- // type information is rich enough we should generalize this to any HType
- // for which the map is known.
- if (HasNoUses() && dominator->IsStoreNamedField()) {
- HStoreNamedField* store = HStoreNamedField::cast(dominator);
- if (!store->has_transition() || store->object() != value()) return false;
- HConstant* transition = HConstant::cast(store->transition());
- if (map_set_.Contains(Unique<Map>::cast(transition->GetUnique()))) {
- DeleteAndReplaceWith(NULL);
- return true;
- }
+void HCheckMaps::PrintDataTo(StringStream* stream) {
+ value()->PrintNameTo(stream);
+ stream->Add(" [%p", *maps()->at(0).handle());
+ for (int i = 1; i < maps()->size(); ++i) {
+ stream->Add(",%p", *maps()->at(i).handle());
}
- return false;
+ stream->Add("]%s", IsStabilityCheck() ? "(stability-check)" : "");
}
-void HCheckMaps::PrintDataTo(StringStream* stream) {
- value()->PrintNameTo(stream);
- stream->Add(" [%p", *map_set_.at(0).handle());
- for (int i = 1; i < map_set_.size(); ++i) {
- stream->Add(",%p", *map_set_.at(i).handle());
+HValue* HCheckMaps::Canonicalize() {
+ if (!IsStabilityCheck() && maps_are_stable() && value()->IsConstant()) {
+ HConstant* c_value = HConstant::cast(value());
+ if (c_value->HasObjectMap()) {
+ for (int i = 0; i < maps()->size(); ++i) {
+ if (c_value->ObjectMap() == maps()->at(i)) {
+ if (maps()->size() > 1) {
+ set_maps(new(block()->graph()->zone()) UniqueSet<Map>(
+ maps()->at(i), block()->graph()->zone()));
+ }
+ MarkAsStabilityCheck();
+ break;
+ }
+ }
+ }
}
- stream->Add("]%s", CanOmitMapChecks() ? "(omitted)" : "");
+ return this;
}
@@ -2467,7 +2483,6 @@ void HPhi::PrintTo(StringStream* stream) {
int32_non_phi_uses() + int32_indirect_uses(),
double_non_phi_uses() + double_indirect_uses(),
tagged_non_phi_uses() + tagged_indirect_uses());
- PrintRangeTo(stream);
PrintTypeTo(stream);
stream->Add("]");
}
@@ -2677,26 +2692,32 @@ static bool IsInteger32(double value) {
}
-HConstant::HConstant(Handle<Object> handle, Representation r)
- : HTemplateInstruction<0>(HType::TypeFromValue(handle)),
- object_(Unique<Object>::CreateUninitialized(handle)),
+HConstant::HConstant(Handle<Object> object, Representation r)
+ : HTemplateInstruction<0>(HType::TypeFromValue(object)),
+ object_(Unique<Object>::CreateUninitialized(object)),
+ object_map_(Handle<Map>::null()),
+ has_stable_map_value_(false),
has_smi_value_(false),
has_int32_value_(false),
has_double_value_(false),
has_external_reference_value_(false),
is_not_in_new_space_(true),
- boolean_value_(handle->BooleanValue()),
+ boolean_value_(object->BooleanValue()),
is_undetectable_(false),
instance_type_(kUnknownInstanceType) {
- if (handle->IsHeapObject()) {
- Handle<HeapObject> heap_obj = Handle<HeapObject>::cast(handle);
- Heap* heap = heap_obj->GetHeap();
- is_not_in_new_space_ = !heap->InNewSpace(*handle);
- instance_type_ = heap_obj->map()->instance_type();
- is_undetectable_ = heap_obj->map()->is_undetectable();
- }
- if (handle->IsNumber()) {
- double n = handle->Number();
+ if (object->IsHeapObject()) {
+ Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
+ Isolate* isolate = heap_object->GetIsolate();
+ Handle<Map> map(heap_object->map(), isolate);
+ is_not_in_new_space_ = !isolate->heap()->InNewSpace(*object);
+ instance_type_ = map->instance_type();
+ is_undetectable_ = map->is_undetectable();
+ if (map->is_stable()) object_map_ = Unique<Map>::CreateImmovable(map);
+ has_stable_map_value_ = (instance_type_ == MAP_TYPE &&
+ Handle<Map>::cast(heap_object)->is_stable());
+ }
+ if (object->IsNumber()) {
+ double n = object->Number();
has_int32_value_ = IsInteger32(n);
int32_value_ = DoubleToInt32(n);
has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_);
@@ -2709,7 +2730,9 @@ HConstant::HConstant(Handle<Object> handle, Representation r)
}
-HConstant::HConstant(Unique<Object> unique,
+HConstant::HConstant(Unique<Object> object,
+ Unique<Map> object_map,
+ bool has_stable_map_value,
Representation r,
HType type,
bool is_not_in_new_space,
@@ -2717,7 +2740,9 @@ HConstant::HConstant(Unique<Object> unique,
bool is_undetectable,
InstanceType instance_type)
: HTemplateInstruction<0>(type),
- object_(unique),
+ object_(object),
+ object_map_(object_map),
+ has_stable_map_value_(has_stable_map_value),
has_smi_value_(false),
has_int32_value_(false),
has_double_value_(false),
@@ -2726,7 +2751,7 @@ HConstant::HConstant(Unique<Object> unique,
boolean_value_(boolean_value),
is_undetectable_(is_undetectable),
instance_type_(instance_type) {
- ASSERT(!unique.handle().is_null());
+ ASSERT(!object.handle().is_null());
ASSERT(!type.IsTaggedNumber());
Initialize(r);
}
@@ -2737,6 +2762,8 @@ HConstant::HConstant(int32_t integer_value,
bool is_not_in_new_space,
Unique<Object> object)
: object_(object),
+ object_map_(Handle<Map>::null()),
+ has_stable_map_value_(false),
has_smi_value_(Smi::IsValid(integer_value)),
has_int32_value_(true),
has_double_value_(true),
@@ -2761,6 +2788,8 @@ HConstant::HConstant(double double_value,
bool is_not_in_new_space,
Unique<Object> object)
: object_(object),
+ object_map_(Handle<Map>::null()),
+ has_stable_map_value_(false),
has_int32_value_(IsInteger32(double_value)),
has_double_value_(true),
has_external_reference_value_(false),
@@ -2783,6 +2812,8 @@ HConstant::HConstant(double double_value,
HConstant::HConstant(ExternalReference reference)
: HTemplateInstruction<0>(HType::None()),
object_(Unique<Object>(Handle<Object>::null())),
+ object_map_(Handle<Map>::null()),
+ has_stable_map_value_(false),
has_smi_value_(false),
has_int32_value_(false),
has_double_value_(false),
@@ -2888,6 +2919,8 @@ HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const {
}
ASSERT(!object_.handle().is_null());
return new(zone) HConstant(object_,
+ object_map_,
+ has_stable_map_value_,
r,
type_,
is_not_in_new_space_,
@@ -2939,6 +2972,13 @@ void HConstant::PrintDataTo(StringStream* stream) {
external_reference_value_.address()));
} else {
handle(Isolate::Current())->ShortPrint(stream);
+ stream->Add(" ");
+ if (HasStableMapValue()) {
+ stream->Add("[stable-map] ");
+ }
+ if (HasObjectMap()) {
+ stream->Add("[map %p] ", *ObjectMap().handle());
+ }
}
if (!is_not_in_new_space_) {
stream->Add("[new space] ");
@@ -3284,6 +3324,21 @@ void HCompareHoleAndBranch::InferRepresentation(
}
+bool HCompareNumericAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
+ if (left() == right() &&
+ left()->representation().IsSmiOrInteger32()) {
+ *block = (token() == Token::EQ ||
+ token() == Token::EQ_STRICT ||
+ token() == Token::LTE ||
+ token() == Token::GTE)
+ ? FirstSuccessor() : SecondSuccessor();
+ return true;
+ }
+ *block = NULL;
+ return false;
+}
+
+
bool HCompareMinusZeroAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
if (FLAG_fold_constants && value()->IsConstant()) {
HConstant* constant = HConstant::cast(value());
@@ -3363,6 +3418,14 @@ void HLoadNamedField::PrintDataTo(StringStream* stream) {
object()->PrintNameTo(stream);
access_.PrintTo(stream);
+ if (maps() != NULL) {
+ stream->Add(" [%p", *maps()->at(0).handle());
+ for (int i = 1; i < maps()->size(); ++i) {
+ stream->Add(",%p", *maps()->at(i).handle());
+ }
+ stream->Add("]");
+ }
+
if (HasDependency()) {
stream->Add(" ");
dependency()->PrintNameTo(stream);
@@ -3370,28 +3433,6 @@ void HLoadNamedField::PrintDataTo(StringStream* stream) {
}
-HCheckMaps* HCheckMaps::New(Zone* zone,
- HValue* context,
- HValue* value,
- Handle<Map> map,
- CompilationInfo* info,
- HValue* typecheck) {
- HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
- check_map->Add(map, zone);
- if (map->CanOmitMapChecks() &&
- value->IsConstant() &&
- HConstant::cast(value)->HasMap(map)) {
- // TODO(titzer): collect dependent map checks into a list.
- check_map->omit_ = true;
- if (map->CanTransition()) {
- map->AddDependentCompilationInfo(
- DependentCode::kPrototypeCheckGroup, info);
- }
- }
- return check_map;
-}
-
-
void HLoadNamedGeneric::PrintDataTo(StringStream* stream) {
object()->PrintNameTo(stream);
stream->Add(".");
@@ -3672,6 +3713,12 @@ HType HChange::CalculateInferredType() {
Representation HUnaryMathOperation::RepresentationFromInputs() {
+ if (SupportsFlexibleFloorAndRound() &&
+ (op_ == kMathFloor || op_ == kMathRound)) {
+ // Floor and Round always take a double input. The integral result can be
+ // used as an integer or a double. Infer the representation from the uses.
+ return Representation::None();
+ }
Representation rep = representation();
// If any of the actual input representation is more general than what we
// have so far but not Tagged, use that representation instead.
@@ -3900,12 +3947,9 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) {
HInnerAllocatedObject::New(zone, context(), dominating_allocate_,
dominating_allocate_->size(), type());
free_space_instr->InsertBefore(this);
- HConstant* filler_map = HConstant::New(
- zone,
- context(),
- isolate()->factory()->free_space_map());
- filler_map->FinalizeUniqueness(); // TODO(titzer): should be init'd a'ready
- filler_map->InsertAfter(free_space_instr);
+ HConstant* filler_map = HConstant::CreateAndInsertAfter(
+ zone, Unique<Map>::CreateImmovable(
+ isolate()->factory()->free_space_map()), free_space_instr);
HInstruction* store_map = HStoreNamedField::New(zone, context(),
free_space_instr, HObjectAccess::ForMap(), filler_map);
store_map->SetFlag(HValue::kHasNoObservableSideEffects);
@@ -4066,7 +4110,7 @@ HInstruction* HStringCharFromCode::New(
if (std::isfinite(c_code->DoubleValue())) {
uint32_t code = c_code->NumberValueAsInteger32() & 0xffff;
return HConstant::New(zone, context,
- LookupSingleCharacterStringFromCode(isolate, code));
+ isolate->factory()->LookupSingleCharacterStringFromCode(code));
}
return HConstant::New(zone, context, isolate->factory()->empty_string());
}
@@ -4140,6 +4184,43 @@ HInstruction* HUnaryMathOperation::New(
}
+Representation HUnaryMathOperation::RepresentationFromUses() {
+ if (op_ != kMathFloor && op_ != kMathRound) {
+ return HValue::RepresentationFromUses();
+ }
+
+ // The instruction can have an int32 or double output. Prefer a double
+ // representation if there are double uses.
+ bool use_double = false;
+
+ for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
+ HValue* use = it.value();
+ int use_index = it.index();
+ Representation rep_observed = use->observed_input_representation(use_index);
+ Representation rep_required = use->RequiredInputRepresentation(use_index);
+ use_double |= (rep_observed.IsDouble() || rep_required.IsDouble());
+ if (use_double && !FLAG_trace_representation) {
+ // Having seen one double is enough.
+ break;
+ }
+ if (FLAG_trace_representation) {
+ if (!rep_required.IsDouble() || rep_observed.IsDouble()) {
+ PrintF("#%d %s is used by #%d %s as %s%s\n",
+ id(), Mnemonic(), use->id(),
+ use->Mnemonic(), rep_observed.Mnemonic(),
+ (use->CheckFlag(kTruncatingToInt32) ? "-trunc" : ""));
+ } else {
+ PrintF("#%d %s is required by #%d %s as %s%s\n",
+ id(), Mnemonic(), use->id(),
+ use->Mnemonic(), rep_required.Mnemonic(),
+ (use->CheckFlag(kTruncatingToInt32) ? "-trunc" : ""));
+ }
+ }
+ }
+ return use_double ? Representation::Double() : Representation::Integer32();
+}
+
+
HInstruction* HPower::New(Zone* zone,
HValue* context,
HValue* left,
@@ -4455,7 +4536,7 @@ void HPhi::Verify() {
void HSimulate::Verify() {
HInstruction::Verify();
- ASSERT(HasAstId());
+ ASSERT(HasAstId() || next()->IsEnterInlined());
}
diff --git a/deps/v8/src/hydrogen-instructions.h b/deps/v8/src/hydrogen-instructions.h
index 1e6ac19bf7..1cdca4c46e 100644
--- a/deps/v8/src/hydrogen-instructions.h
+++ b/deps/v8/src/hydrogen-instructions.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_INSTRUCTIONS_H_
#define V8_HYDROGEN_INSTRUCTIONS_H_
@@ -32,13 +9,13 @@
#include "allocation.h"
#include "code-stubs.h"
+#include "conversions.h"
#include "data-flow.h"
#include "deoptimizer.h"
#include "small-pointer-list.h"
#include "string-stream.h"
#include "unique.h"
-#include "v8conversions.h"
-#include "v8utils.h"
+#include "utils.h"
#include "zone.h"
namespace v8 {
@@ -184,7 +161,6 @@ class LChunkBuilder;
V(WrapReceiver)
#define GVN_TRACKED_FLAG_LIST(V) \
- V(Maps) \
V(NewSpacePromotion)
#define GVN_UNTRACKED_FLAG_LIST(V) \
@@ -200,6 +176,7 @@ class LChunkBuilder;
V(ElementsPointer) \
V(GlobalVars) \
V(InobjectFields) \
+ V(Maps) \
V(OsrEntries) \
V(ExternalMemory) \
V(StringChars) \
@@ -678,12 +655,19 @@ class HValue : public ZoneObject {
HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
#undef DECLARE_PREDICATE
+ bool IsBitwiseBinaryShift() {
+ return IsShl() || IsShr() || IsSar();
+ }
+
HValue(HType type = HType::Tagged())
: block_(NULL),
id_(kNoNumber),
type_(type),
use_list_(NULL),
range_(NULL),
+#ifdef DEBUG
+ range_poisoned_(false),
+#endif
flags_(0) {}
virtual ~HValue() {}
@@ -854,9 +838,17 @@ class HValue : public ZoneObject {
return result;
}
- Range* range() const { return range_; }
- // TODO(svenpanne) We should really use the null object pattern here.
- bool HasRange() const { return range_ != NULL; }
+ Range* range() const {
+ ASSERT(!range_poisoned_);
+ return range_;
+ }
+ bool HasRange() const {
+ ASSERT(!range_poisoned_);
+ return range_ != NULL;
+ }
+#ifdef DEBUG
+ void PoisonRange() { range_poisoned_ = true; }
+#endif
void AddNewRange(Range* r, Zone* zone);
void RemoveLastAddedRange();
void ComputeInitialRange(Zone* zone);
@@ -888,7 +880,6 @@ class HValue : public ZoneObject {
virtual void PrintTo(StringStream* stream) = 0;
void PrintNameTo(StringStream* stream);
void PrintTypeTo(StringStream* stream);
- void PrintRangeTo(StringStream* stream);
void PrintChangesTo(StringStream* stream);
const char* Mnemonic() const;
@@ -962,7 +953,7 @@ class HValue : public ZoneObject {
virtual Representation RepresentationFromInputs() {
return representation();
}
- Representation RepresentationFromUses();
+ virtual Representation RepresentationFromUses();
Representation RepresentationFromUseRequirements();
bool HasNonSmiUse();
virtual void UpdateRepresentation(Representation new_rep,
@@ -1028,6 +1019,9 @@ class HValue : public ZoneObject {
HType type_;
HUseListNode* use_list_;
Range* range_;
+#ifdef DEBUG
+ bool range_poisoned_;
+#endif
int flags_;
GVNFlagSet changes_flags_;
GVNFlagSet depends_on_flags_;
@@ -1263,6 +1257,7 @@ class HInstruction : public HValue {
position_.set_operand_position(index, pos);
}
+ bool CanTruncateToSmi() const { return CheckFlag(kTruncatingToSmi); }
bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
@@ -1529,6 +1524,8 @@ class HBranch V8_FINAL : public HUnaryControlInstruction {
virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE;
+ virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
+
ToBooleanStub::Types expected_input_types() const {
return expected_input_types_;
}
@@ -1733,7 +1730,7 @@ class HChange V8_FINAL : public HUnaryOperation {
set_representation(to);
SetFlag(kUseGVN);
SetFlag(kCanOverflow);
- if (is_truncating_to_smi) {
+ if (is_truncating_to_smi && to.IsSmi()) {
SetFlag(kTruncatingToSmi);
SetFlag(kTruncatingToInt32);
}
@@ -2069,14 +2066,15 @@ class HEnterInlined V8_FINAL : public HTemplateInstruction<0> {
public:
static HEnterInlined* New(Zone* zone,
HValue* context,
+ BailoutId return_id,
Handle<JSFunction> closure,
int arguments_count,
FunctionLiteral* function,
InliningKind inlining_kind,
Variable* arguments_var,
HArgumentsObject* arguments_object) {
- return new(zone) HEnterInlined(closure, arguments_count, function,
- inlining_kind, arguments_var,
+ return new(zone) HEnterInlined(return_id, closure, arguments_count,
+ function, inlining_kind, arguments_var,
arguments_object, zone);
}
@@ -2091,6 +2089,7 @@ class HEnterInlined V8_FINAL : public HTemplateInstruction<0> {
void set_arguments_pushed() { arguments_pushed_ = true; }
FunctionLiteral* function() const { return function_; }
InliningKind inlining_kind() const { return inlining_kind_; }
+ BailoutId ReturnId() const { return return_id_; }
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
return Representation::None();
@@ -2102,14 +2101,16 @@ class HEnterInlined V8_FINAL : public HTemplateInstruction<0> {
DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
private:
- HEnterInlined(Handle<JSFunction> closure,
+ HEnterInlined(BailoutId return_id,
+ Handle<JSFunction> closure,
int arguments_count,
FunctionLiteral* function,
InliningKind inlining_kind,
Variable* arguments_var,
HArgumentsObject* arguments_object,
Zone* zone)
- : closure_(closure),
+ : return_id_(return_id),
+ closure_(closure),
arguments_count_(arguments_count),
arguments_pushed_(false),
function_(function),
@@ -2119,6 +2120,7 @@ class HEnterInlined V8_FINAL : public HTemplateInstruction<0> {
return_targets_(2, zone) {
}
+ BailoutId return_id_;
Handle<JSFunction> closure_;
int arguments_count_;
bool arguments_pushed_;
@@ -2640,6 +2642,7 @@ class HUnaryMathOperation V8_FINAL : public HTemplateInstruction<2> {
virtual Range* InferRange(Zone* zone) V8_OVERRIDE;
virtual HValue* Canonicalize() V8_OVERRIDE;
+ virtual Representation RepresentationFromUses() V8_OVERRIDE;
virtual Representation RepresentationFromInputs() V8_OVERRIDE;
BuiltinFunctionId op() const { return op_; }
@@ -2654,6 +2657,15 @@ class HUnaryMathOperation V8_FINAL : public HTemplateInstruction<2> {
}
private:
+ // Indicates if we support a double (and int32) output for Math.floor and
+ // Math.round.
+ bool SupportsFlexibleFloorAndRound() const {
+#ifdef V8_TARGET_ARCH_ARM64
+ return true;
+#else
+ return false;
+#endif
+ }
HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
: HTemplateInstruction<2>(HType::TaggedNumber()), op_(op) {
SetOperandAt(0, context);
@@ -2661,6 +2673,12 @@ class HUnaryMathOperation V8_FINAL : public HTemplateInstruction<2> {
switch (op) {
case kMathFloor:
case kMathRound:
+ if (SupportsFlexibleFloorAndRound()) {
+ SetFlag(kFlexibleRepresentation);
+ } else {
+ set_representation(Representation::Integer32());
+ }
+ break;
case kMathClz32:
set_representation(Representation::Integer32());
break;
@@ -2730,81 +2748,112 @@ class HLoadRoot V8_FINAL : public HTemplateInstruction<0> {
class HCheckMaps V8_FINAL : public HTemplateInstruction<2> {
public:
static HCheckMaps* New(Zone* zone, HValue* context, HValue* value,
- Handle<Map> map, CompilationInfo* info,
- HValue* typecheck = NULL);
+ Handle<Map> map, HValue* typecheck = NULL) {
+ return new(zone) HCheckMaps(value, new(zone) UniqueSet<Map>(
+ Unique<Map>::CreateImmovable(map), zone), typecheck);
+ }
static HCheckMaps* New(Zone* zone, HValue* context,
- HValue* value, SmallMapList* maps,
+ HValue* value, SmallMapList* map_list,
HValue* typecheck = NULL) {
- HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
- for (int i = 0; i < maps->length(); i++) {
- check_map->Add(maps->at(i), zone);
+ UniqueSet<Map>* maps = new(zone) UniqueSet<Map>(map_list->length(), zone);
+ for (int i = 0; i < map_list->length(); ++i) {
+ maps->Add(Unique<Map>::CreateImmovable(map_list->at(i)), zone);
}
- return check_map;
+ return new(zone) HCheckMaps(value, maps, typecheck);
}
- bool CanOmitMapChecks() { return omit_; }
+ bool IsStabilityCheck() const { return is_stability_check_; }
+ void MarkAsStabilityCheck() {
+ has_migration_target_ = false;
+ is_stability_check_ = true;
+ ClearChangesFlag(kNewSpacePromotion);
+ ClearDependsOnFlag(kElementsKind);
+ ClearDependsOnFlag(kMaps);
+ }
virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; }
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
return Representation::Tagged();
}
- virtual bool HandleSideEffectDominator(GVNFlag side_effect,
- HValue* dominator) V8_OVERRIDE;
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
HValue* value() { return OperandAt(0); }
HValue* typecheck() { return OperandAt(1); }
- Unique<Map> first_map() const { return map_set_.at(0); }
- UniqueSet<Map> map_set() const { return map_set_; }
+ const UniqueSet<Map>* maps() const { return maps_; }
+ void set_maps(const UniqueSet<Map>* maps) { maps_ = maps; }
- void set_map_set(UniqueSet<Map>* maps, Zone *zone) {
- map_set_.Clear();
- for (int i = 0; i < maps->size(); i++) {
- map_set_.Add(maps->at(i), zone);
- }
+ bool maps_are_stable() const { return maps_are_stable_; }
+
+ bool HasMigrationTarget() const { return has_migration_target_; }
+
+ virtual HValue* Canonicalize() V8_OVERRIDE;
+
+ static HCheckMaps* CreateAndInsertAfter(Zone* zone,
+ HValue* value,
+ Unique<Map> map,
+ bool map_is_stable,
+ HInstruction* instr) {
+ return CreateAndInsertAfter(zone, value, new(zone) UniqueSet<Map>(
+ map, zone), map_is_stable, instr);
}
- bool has_migration_target() const {
- return has_migration_target_;
+ static HCheckMaps* CreateAndInsertAfter(Zone* zone,
+ HValue* value,
+ const UniqueSet<Map>* maps,
+ bool maps_are_stable,
+ HInstruction* instr) {
+ return instr->Append(new(zone) HCheckMaps(value, maps, maps_are_stable));
}
DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
protected:
virtual bool DataEquals(HValue* other) V8_OVERRIDE {
- return this->map_set_.Equals(&HCheckMaps::cast(other)->map_set_);
+ return this->maps()->Equals(HCheckMaps::cast(other)->maps());
}
virtual int RedefinedOperandIndex() { return 0; }
private:
- void Add(Handle<Map> map, Zone* zone) {
- map_set_.Add(Unique<Map>(map), zone);
+ HCheckMaps(HValue* value, const UniqueSet<Map>* maps, bool maps_are_stable)
+ : HTemplateInstruction<2>(value->type()), maps_(maps),
+ has_migration_target_(false), is_stability_check_(false),
+ maps_are_stable_(maps_are_stable) {
+ ASSERT_NE(0, maps->size());
+ SetOperandAt(0, value);
+ // Use the object value for the dependency.
+ SetOperandAt(1, value);
+ set_representation(Representation::Tagged());
+ SetFlag(kUseGVN);
SetDependsOnFlag(kMaps);
SetDependsOnFlag(kElementsKind);
-
- if (!has_migration_target_ && map->is_migration_target()) {
- has_migration_target_ = true;
- SetChangesFlag(kNewSpacePromotion);
- }
}
- // Clients should use one of the static New* methods above.
- HCheckMaps(HValue* value, Zone *zone, HValue* typecheck)
- : HTemplateInstruction<2>(value->type()),
- omit_(false), has_migration_target_(false) {
+ HCheckMaps(HValue* value, const UniqueSet<Map>* maps, HValue* typecheck)
+ : HTemplateInstruction<2>(value->type()), maps_(maps),
+ has_migration_target_(false), is_stability_check_(false),
+ maps_are_stable_(true) {
+ ASSERT_NE(0, maps->size());
SetOperandAt(0, value);
// Use the object value for the dependency if NULL is passed.
- SetOperandAt(1, typecheck != NULL ? typecheck : value);
+ SetOperandAt(1, typecheck ? typecheck : value);
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
- SetFlag(kTrackSideEffectDominators);
+ SetDependsOnFlag(kMaps);
+ SetDependsOnFlag(kElementsKind);
+ for (int i = 0; i < maps->size(); ++i) {
+ Handle<Map> map = maps->at(i).handle();
+ if (map->is_migration_target()) has_migration_target_ = true;
+ if (!map->is_stable()) maps_are_stable_ = false;
+ }
+ if (has_migration_target_) SetChangesFlag(kNewSpacePromotion);
}
- bool omit_;
- bool has_migration_target_;
- UniqueSet<Map> map_set_;
+ const UniqueSet<Map>* maps_;
+ bool has_migration_target_ : 1;
+ bool is_stability_check_ : 1;
+ bool maps_are_stable_ : 1;
};
@@ -3377,8 +3426,6 @@ class HArgumentsObject V8_FINAL : public HDematerializedObject {
set_representation(Representation::Tagged());
SetFlag(kIsArguments);
}
-
- virtual bool IsDeletable() const V8_FINAL V8_OVERRIDE { return true; }
};
@@ -3450,12 +3497,22 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
}
static HConstant* CreateAndInsertBefore(Zone* zone,
- Unique<Object> unique,
+ Unique<Object> object,
bool is_not_in_new_space,
HInstruction* instruction) {
return instruction->Prepend(new(zone) HConstant(
- unique, Representation::Tagged(), HType::Tagged(),
- is_not_in_new_space, false, false, kUnknownInstanceType));
+ object, Unique<Map>(Handle<Map>::null()), false,
+ Representation::Tagged(), HType::Tagged(), is_not_in_new_space,
+ false, false, kUnknownInstanceType));
+ }
+
+ static HConstant* CreateAndInsertAfter(Zone* zone,
+ Unique<Map> map,
+ HInstruction* instruction) {
+ return instruction->Append(new(zone) HConstant(
+ map, Unique<Map>(Handle<Map>::null()), false,
+ Representation::Tagged(), HType::Tagged(), true,
+ false, false, MAP_TYPE));
}
Handle<Object> handle(Isolate* isolate) {
@@ -3470,12 +3527,6 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
return object_.handle();
}
- bool HasMap(Handle<Map> map) {
- Handle<Object> constant_object = handle(map->GetIsolate());
- return constant_object->IsHeapObject() &&
- Handle<HeapObject>::cast(constant_object)->map() == *map;
- }
-
bool IsSpecialDouble() const {
return has_double_value_ &&
(BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) ||
@@ -3560,6 +3611,22 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
bool IsUndetectable() const { return is_undetectable_; }
InstanceType GetInstanceType() const { return instance_type_; }
+ bool HasMapValue() const { return instance_type_ == MAP_TYPE; }
+ Unique<Map> MapValue() const {
+ ASSERT(HasMapValue());
+ return Unique<Map>::cast(GetUnique());
+ }
+ bool HasStableMapValue() const {
+ ASSERT(HasMapValue() || !has_stable_map_value_);
+ return has_stable_map_value_;
+ }
+
+ bool HasObjectMap() const { return !object_map_.IsNull(); }
+ Unique<Map> ObjectMap() const {
+ ASSERT(HasObjectMap());
+ return object_map_;
+ }
+
virtual intptr_t Hashcode() V8_OVERRIDE {
if (has_int32_value_) {
return static_cast<intptr_t>(int32_value_);
@@ -3632,7 +3699,9 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
Representation r = Representation::None(),
bool is_not_in_new_space = true,
Unique<Object> optional = Unique<Object>(Handle<Object>::null()));
- HConstant(Unique<Object> unique,
+ HConstant(Unique<Object> object,
+ Unique<Map> object_map,
+ bool has_stable_map_value,
Representation r,
HType type,
bool is_not_in_new_space,
@@ -3652,6 +3721,12 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
// constant HeapObject.
Unique<Object> object_;
+ // If object_ is a heap object, this points to the stable map of the object.
+ Unique<Map> object_map_;
+
+ // If object_ is a map, this indicates whether the map is stable.
+ bool has_stable_map_value_ : 1;
+
// We store the HConstant in the most specific form safely possible.
// The two flags, has_int32_value_ and has_double_value_ tell us if
// int32_value_ and double_value_ hold valid, safe representations
@@ -3761,7 +3836,7 @@ class HBinaryOperation : public HTemplateInstruction<3> {
bool RightIsPowerOf2() {
if (!right()->IsInteger32Constant()) return false;
int32_t value = right()->GetInteger32Constant();
- return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
+ return IsPowerOf2(value) || IsPowerOf2(-value);
}
DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
@@ -4206,6 +4281,9 @@ class HCompareNumericAndBranch : public HTemplateControlInstruction<2, 2> {
virtual Representation observed_input_representation(int index) V8_OVERRIDE {
return observed_input_representation_[index];
}
+
+ virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE;
+
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
void SetOperandPositions(Zone* zone,
@@ -5818,6 +5896,10 @@ class HObjectAccess V8_FINAL {
return portion() == kStringLengths;
}
+ inline bool IsMap() const {
+ return portion() == kMaps;
+ }
+
inline int offset() const {
return OffsetField::decode(value_);
}
@@ -6025,6 +6107,11 @@ class HObjectAccess V8_FINAL {
JSArrayBuffer::kBackingStoreOffset, Representation::External());
}
+ static HObjectAccess ForJSArrayBufferByteLength() {
+ return HObjectAccess::ForObservableJSObjectOffset(
+ JSArrayBuffer::kByteLengthOffset, Representation::Tagged());
+ }
+
static HObjectAccess ForExternalArrayExternalPointer() {
return HObjectAccess::ForObservableJSObjectOffset(
ExternalArray::kExternalPointerOffset, Representation::External());
@@ -6125,8 +6212,10 @@ class HObjectAccess V8_FINAL {
class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> {
public:
- DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, HValue*,
- HObjectAccess);
+ DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*,
+ HValue*, HObjectAccess);
+ DECLARE_INSTRUCTION_FACTORY_P5(HLoadNamedField, HValue*, HValue*,
+ HObjectAccess, const UniqueSet<Map>*, HType);
HValue* object() { return OperandAt(0); }
HValue* dependency() {
@@ -6139,6 +6228,8 @@ class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> {
return access_.representation();
}
+ const UniqueSet<Map>* maps() const { return maps_; }
+
virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; }
virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE {
return !access().IsInobject() || access().offset() >= size;
@@ -6153,21 +6244,36 @@ class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> {
virtual Range* InferRange(Zone* zone) V8_OVERRIDE;
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
+ bool CanBeReplacedWith(HValue* other) const {
+ if (!type().Equals(other->type())) return false;
+ if (!representation().Equals(other->representation())) return false;
+ if (!other->IsLoadNamedField()) return true;
+ HLoadNamedField* that = HLoadNamedField::cast(other);
+ if (this->maps_ == that->maps_) return true;
+ if (this->maps_ == NULL || that->maps_ == NULL) return false;
+ return this->maps_->IsSubset(that->maps_);
+ }
+
DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
protected:
virtual bool DataEquals(HValue* other) V8_OVERRIDE {
- HLoadNamedField* b = HLoadNamedField::cast(other);
- return access_.Equals(b->access_);
+ HLoadNamedField* that = HLoadNamedField::cast(other);
+ if (!this->access_.Equals(that->access_)) return false;
+ if (this->maps_ == that->maps_) return true;
+ return (this->maps_ != NULL &&
+ that->maps_ != NULL &&
+ this->maps_->Equals(that->maps_));
}
private:
HLoadNamedField(HValue* object,
HValue* dependency,
- HObjectAccess access) : access_(access) {
- ASSERT(object != NULL);
+ HObjectAccess access)
+ : access_(access), maps_(NULL) {
+ ASSERT_NOT_NULL(object);
SetOperandAt(0, object);
- SetOperandAt(1, dependency != NULL ? dependency : object);
+ SetOperandAt(1, dependency ? dependency : object);
Representation representation = access.representation();
if (representation.IsInteger8() ||
@@ -6187,6 +6293,8 @@ class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> {
representation.IsInteger32()) {
set_representation(representation);
} else if (representation.IsHeapObject()) {
+ // TODO(bmeurer): This is probably broken. What we actually want to to
+ // instead is set_representation(Representation::HeapObject()).
set_type(HType::NonPrimitive());
set_representation(Representation::Tagged());
} else {
@@ -6195,9 +6303,32 @@ class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> {
access.SetGVNFlags(this, LOAD);
}
+ HLoadNamedField(HValue* object,
+ HValue* dependency,
+ HObjectAccess access,
+ const UniqueSet<Map>* maps,
+ HType type)
+ : HTemplateInstruction<2>(type), access_(access), maps_(maps) {
+ ASSERT_NOT_NULL(maps);
+ ASSERT_NE(0, maps->size());
+
+ ASSERT_NOT_NULL(object);
+ SetOperandAt(0, object);
+ SetOperandAt(1, dependency ? dependency : object);
+
+ ASSERT(access.representation().IsHeapObject());
+ // TODO(bmeurer): This is probably broken. What we actually want to to
+ // instead is set_representation(Representation::HeapObject()).
+ if (!type.IsHeapObject()) set_type(HType::NonPrimitive());
+ set_representation(Representation::Tagged());
+
+ access.SetGVNFlags(this, LOAD);
+ }
+
virtual bool IsDeletable() const V8_OVERRIDE { return true; }
HObjectAccess access_;
+ const UniqueSet<Map>* maps_;
};
@@ -6573,13 +6704,9 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
}
}
- void SetTransition(HConstant* map_constant, CompilationInfo* info) {
+ void SetTransition(HConstant* transition) {
ASSERT(!has_transition()); // Only set once.
- Handle<Map> map = Handle<Map>::cast(map_constant->handle(info->isolate()));
- if (map->CanBeDeprecated()) {
- map->AddDependentCompilationInfo(DependentCode::kTransitionGroup, info);
- }
- SetOperandAt(2, map_constant);
+ SetOperandAt(2, transition);
has_transition_ = true;
}
@@ -7399,6 +7526,8 @@ class HCheckMapValue V8_FINAL : public HTemplateInstruction<2> {
HValue* value() { return OperandAt(0); }
HValue* map() { return OperandAt(1); }
+ virtual HValue* Canonicalize() V8_OVERRIDE;
+
DECLARE_CONCRETE_INSTRUCTION(CheckMapValue)
protected:
@@ -7499,6 +7628,7 @@ class HLoadFieldByIndex V8_FINAL : public HTemplateInstruction<2> {
HValue* index) {
SetOperandAt(0, object);
SetOperandAt(1, index);
+ SetChangesFlag(kNewSpacePromotion);
set_representation(Representation::Tagged());
}
diff --git a/deps/v8/src/hydrogen-load-elimination.cc b/deps/v8/src/hydrogen-load-elimination.cc
index f84eac046b..1198d2b7ab 100644
--- a/deps/v8/src/hydrogen-load-elimination.cc
+++ b/deps/v8/src/hydrogen-load-elimination.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-alias-analysis.h"
#include "hydrogen-load-elimination.h"
@@ -76,9 +53,7 @@ class HLoadEliminationTable : public ZoneObject {
FieldOf(l->access()),
l->object()->ActualValue()->id()));
HValue* result = load(l);
- if (result != instr &&
- result->type().Equals(instr->type()) &&
- result->representation().Equals(instr->representation())) {
+ if (result != instr && l->CanBeReplacedWith(result)) {
// The load can be replaced with a previous load or a value.
TRACE((" replace L%d -> v%d\n", instr->id(), result->id()));
instr->DeleteAndReplaceWith(result);
diff --git a/deps/v8/src/hydrogen-load-elimination.h b/deps/v8/src/hydrogen-load-elimination.h
index ef6f71fa11..98cd03d583 100644
--- a/deps/v8/src/hydrogen-load-elimination.h
+++ b/deps/v8/src/hydrogen-load-elimination.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_LOAD_ELIMINATION_H_
#define V8_HYDROGEN_LOAD_ELIMINATION_H_
diff --git a/deps/v8/src/hydrogen-mark-deoptimize.cc b/deps/v8/src/hydrogen-mark-deoptimize.cc
index c0236e91cb..338e239e20 100644
--- a/deps/v8/src/hydrogen-mark-deoptimize.cc
+++ b/deps/v8/src/hydrogen-mark-deoptimize.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-mark-deoptimize.h"
diff --git a/deps/v8/src/hydrogen-mark-deoptimize.h b/deps/v8/src/hydrogen-mark-deoptimize.h
index 30f35b3dec..7b302fcc26 100644
--- a/deps/v8/src/hydrogen-mark-deoptimize.h
+++ b/deps/v8/src/hydrogen-mark-deoptimize.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_MARK_DEOPTIMIZE_H_
#define V8_HYDROGEN_MARK_DEOPTIMIZE_H_
diff --git a/deps/v8/src/hydrogen-mark-unreachable.cc b/deps/v8/src/hydrogen-mark-unreachable.cc
index d7c5ed2b18..c80de639e2 100644
--- a/deps/v8/src/hydrogen-mark-unreachable.cc
+++ b/deps/v8/src/hydrogen-mark-unreachable.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-mark-unreachable.h"
diff --git a/deps/v8/src/hydrogen-mark-unreachable.h b/deps/v8/src/hydrogen-mark-unreachable.h
index 9ecc6e9f16..a406c5cff1 100644
--- a/deps/v8/src/hydrogen-mark-unreachable.h
+++ b/deps/v8/src/hydrogen-mark-unreachable.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_MARK_UNREACHABLE_H_
#define V8_HYDROGEN_MARK_UNREACHABLE_H_
diff --git a/deps/v8/src/hydrogen-osr.cc b/deps/v8/src/hydrogen-osr.cc
index 6e39df6aa9..ff46ea7ebc 100644
--- a/deps/v8/src/hydrogen-osr.cc
+++ b/deps/v8/src/hydrogen-osr.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen.h"
#include "hydrogen-osr.h"
diff --git a/deps/v8/src/hydrogen-osr.h b/deps/v8/src/hydrogen-osr.h
index ae72ce650c..00bb2d4e19 100644
--- a/deps/v8/src/hydrogen-osr.h
+++ b/deps/v8/src/hydrogen-osr.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_OSR_H_
#define V8_HYDROGEN_OSR_H_
diff --git a/deps/v8/src/hydrogen-range-analysis.cc b/deps/v8/src/hydrogen-range-analysis.cc
index 9d58fc89f0..609dd88fa1 100644
--- a/deps/v8/src/hydrogen-range-analysis.cc
+++ b/deps/v8/src/hydrogen-range-analysis.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-range-analysis.h"
@@ -123,6 +100,22 @@ void HRangeAnalysisPhase::Run() {
block = NULL;
}
}
+
+ // The ranges are not valid anymore due to SSI vs. SSA!
+ PoisonRanges();
+}
+
+
+void HRangeAnalysisPhase::PoisonRanges() {
+#ifdef DEBUG
+ for (int i = 0; i < graph()->blocks()->length(); ++i) {
+ HBasicBlock* block = graph()->blocks()->at(i);
+ for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+ HInstruction* instr = it.Current();
+ if (instr->HasRange()) instr->PoisonRange();
+ }
+ }
+#endif
}
diff --git a/deps/v8/src/hydrogen-range-analysis.h b/deps/v8/src/hydrogen-range-analysis.h
index e0cc3c5dad..2ed2ecb22e 100644
--- a/deps/v8/src/hydrogen-range-analysis.h
+++ b/deps/v8/src/hydrogen-range-analysis.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_RANGE_ANALYSIS_H_
#define V8_HYDROGEN_RANGE_ANALYSIS_H_
@@ -57,6 +34,7 @@ class HRangeAnalysisPhase : public HPhase {
worklist_.Add(value, zone());
}
void PropagateMinusZeroChecks(HValue* value);
+ void PoisonRanges();
ZoneList<HValue*> changed_ranges_;
diff --git a/deps/v8/src/hydrogen-redundant-phi.cc b/deps/v8/src/hydrogen-redundant-phi.cc
index 1263833dac..5757cfb0a3 100644
--- a/deps/v8/src/hydrogen-redundant-phi.cc
+++ b/deps/v8/src/hydrogen-redundant-phi.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-redundant-phi.h"
diff --git a/deps/v8/src/hydrogen-redundant-phi.h b/deps/v8/src/hydrogen-redundant-phi.h
index 960ae69c95..9e1092b398 100644
--- a/deps/v8/src/hydrogen-redundant-phi.h
+++ b/deps/v8/src/hydrogen-redundant-phi.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_REDUNDANT_PHI_H_
#define V8_HYDROGEN_REDUNDANT_PHI_H_
diff --git a/deps/v8/src/hydrogen-removable-simulates.cc b/deps/v8/src/hydrogen-removable-simulates.cc
index f952832431..7bbe3cbf28 100644
--- a/deps/v8/src/hydrogen-removable-simulates.cc
+++ b/deps/v8/src/hydrogen-removable-simulates.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-removable-simulates.h"
@@ -41,14 +18,17 @@ void HMergeRemovableSimulatesPhase::Run() {
bool first = true;
for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
HInstruction* current = it.Current();
+ if (current->IsEnterInlined()) {
+ // Ensure there's a non-foldable HSimulate before an HEnterInlined to
+ // avoid folding across HEnterInlined.
+ ASSERT(!HSimulate::cast(current->previous())->
+ is_candidate_for_removal());
+ }
if (current->IsLeaveInlined()) {
- // Never fold simulates from inlined environments into simulates
- // in the outer environment.
- // (Before each HEnterInlined, there is a non-foldable HSimulate
- // anyway, so we get the barrier in the other direction for free.)
- // Simply remove all accumulated simulates without merging. This
- // is safe because simulates after instructions with side effects
- // are never added to the merge list.
+ // Never fold simulates from inlined environments into simulates in the
+ // outer environment. Simply remove all accumulated simulates without
+ // merging. This is safe because simulates after instructions with side
+ // effects are never added to the merge list.
while (!mergelist.is_empty()) {
mergelist.RemoveLast()->DeleteAndReplaceWith(NULL);
}
@@ -70,13 +50,24 @@ void HMergeRemovableSimulatesPhase::Run() {
continue;
}
HSimulate* current_simulate = HSimulate::cast(current);
- if ((current_simulate->previous()->HasObservableSideEffects() &&
- !current_simulate->next()->IsSimulate()) ||
- !current_simulate->is_candidate_for_removal()) {
- // This simulate is not suitable for folding.
- // Fold the ones accumulated so far.
+ if (!current_simulate->is_candidate_for_removal()) {
+ current_simulate->MergeWith(&mergelist);
+ } else if (current_simulate->ast_id().IsNone()) {
+ ASSERT(current_simulate->next()->IsEnterInlined());
+ if (!mergelist.is_empty()) {
+ HSimulate* last = mergelist.RemoveLast();
+ last->MergeWith(&mergelist);
+ }
+ } else if (current_simulate->previous()->HasObservableSideEffects()) {
+ while (current_simulate->next()->IsSimulate()) {
+ it.Advance();
+ HSimulate* next_simulate = HSimulate::cast(it.Current());
+ if (next_simulate->ast_id().IsNone()) break;
+ mergelist.Add(current_simulate, zone());
+ current_simulate = next_simulate;
+ if (!current_simulate->is_candidate_for_removal()) break;
+ }
current_simulate->MergeWith(&mergelist);
- continue;
} else {
// Accumulate this simulate for folding later on.
mergelist.Add(current_simulate, zone());
diff --git a/deps/v8/src/hydrogen-removable-simulates.h b/deps/v8/src/hydrogen-removable-simulates.h
index f5bcd6ddfa..aec5fce1d2 100644
--- a/deps/v8/src/hydrogen-removable-simulates.h
+++ b/deps/v8/src/hydrogen-removable-simulates.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_REMOVABLE_SIMULATES_H_
#define V8_HYDROGEN_REMOVABLE_SIMULATES_H_
diff --git a/deps/v8/src/hydrogen-representation-changes.cc b/deps/v8/src/hydrogen-representation-changes.cc
index 0b87d12eb3..15f1a6e444 100644
--- a/deps/v8/src/hydrogen-representation-changes.cc
+++ b/deps/v8/src/hydrogen-representation-changes.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-representation-changes.h"
diff --git a/deps/v8/src/hydrogen-representation-changes.h b/deps/v8/src/hydrogen-representation-changes.h
index 77e899b60b..ff57e19292 100644
--- a/deps/v8/src/hydrogen-representation-changes.h
+++ b/deps/v8/src/hydrogen-representation-changes.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_REPRESENTATION_CHANGES_H_
#define V8_HYDROGEN_REPRESENTATION_CHANGES_H_
diff --git a/deps/v8/src/hydrogen-sce.cc b/deps/v8/src/hydrogen-sce.cc
index 70b0a0c082..dfb3a7e3ac 100644
--- a/deps/v8/src/hydrogen-sce.cc
+++ b/deps/v8/src/hydrogen-sce.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-sce.h"
#include "v8.h"
diff --git a/deps/v8/src/hydrogen-sce.h b/deps/v8/src/hydrogen-sce.h
index 55e153e0ed..48ac8e3319 100644
--- a/deps/v8/src/hydrogen-sce.h
+++ b/deps/v8/src/hydrogen-sce.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_SCE_H_
#define V8_HYDROGEN_SCE_H_
diff --git a/deps/v8/src/hydrogen-store-elimination.cc b/deps/v8/src/hydrogen-store-elimination.cc
index 2e6ee51387..cf5f3a15e6 100644
--- a/deps/v8/src/hydrogen-store-elimination.cc
+++ b/deps/v8/src/hydrogen-store-elimination.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-store-elimination.h"
#include "hydrogen-instructions.h"
@@ -129,7 +106,7 @@ void HStoreEliminationPhase::ProcessInstr(HInstruction* instr,
unobserved_.Rewind(0);
return;
}
- if (instr->ChangesFlags().ContainsAnyOf(flags)) {
+ if (instr->DependsOnFlags().ContainsAnyOf(flags)) {
TRACE(("-- Observed stores at I%d (GVN flags)\n", instr->id()));
unobserved_.Rewind(0);
return;
diff --git a/deps/v8/src/hydrogen-store-elimination.h b/deps/v8/src/hydrogen-store-elimination.h
index 7dc871c9ba..e697708c33 100644
--- a/deps/v8/src/hydrogen-store-elimination.h
+++ b/deps/v8/src/hydrogen-store-elimination.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_STORE_ELIMINATION_H_
#define V8_HYDROGEN_STORE_ELIMINATION_H_
diff --git a/deps/v8/src/hydrogen-uint32-analysis.cc b/deps/v8/src/hydrogen-uint32-analysis.cc
index 63b1de697e..21fbec9f33 100644
--- a/deps/v8/src/hydrogen-uint32-analysis.cc
+++ b/deps/v8/src/hydrogen-uint32-analysis.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen-uint32-analysis.h"
diff --git a/deps/v8/src/hydrogen-uint32-analysis.h b/deps/v8/src/hydrogen-uint32-analysis.h
index 59739d1ccf..8d672ac6a6 100644
--- a/deps/v8/src/hydrogen-uint32-analysis.h
+++ b/deps/v8/src/hydrogen-uint32-analysis.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_UINT32_ANALYSIS_H_
#define V8_HYDROGEN_UINT32_ANALYSIS_H_
diff --git a/deps/v8/src/hydrogen.cc b/deps/v8/src/hydrogen.cc
index a7ef0cbd05..ee9f8e4167 100644
--- a/deps/v8/src/hydrogen.cc
+++ b/deps/v8/src/hydrogen.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "hydrogen.h"
@@ -701,11 +678,13 @@ HConstant* HGraph::GetConstantMinus1() {
}
-#define DEFINE_GET_CONSTANT(Name, name, htype, boolean_value) \
+#define DEFINE_GET_CONSTANT(Name, name, type, htype, boolean_value) \
HConstant* HGraph::GetConstant##Name() { \
if (!constant_##name##_.is_set()) { \
HConstant* constant = new(zone()) HConstant( \
Unique<Object>::CreateImmovable(isolate()->factory()->name##_value()), \
+ Unique<Map>::CreateImmovable(isolate()->factory()->type##_map()), \
+ false, \
Representation::Tagged(), \
htype, \
true, \
@@ -719,11 +698,11 @@ HConstant* HGraph::GetConstant##Name() { \
}
-DEFINE_GET_CONSTANT(Undefined, undefined, HType::Tagged(), false)
-DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true)
-DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false)
-DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false)
-DEFINE_GET_CONSTANT(Null, null, HType::Tagged(), false)
+DEFINE_GET_CONSTANT(Undefined, undefined, undefined, HType::Tagged(), false)
+DEFINE_GET_CONSTANT(True, true, boolean, HType::Boolean(), true)
+DEFINE_GET_CONSTANT(False, false, boolean, HType::Boolean(), false)
+DEFINE_GET_CONSTANT(Hole, the_hole, the_hole, HType::Tagged(), false)
+DEFINE_GET_CONSTANT(Null, null, null, HType::Tagged(), false)
#undef DEFINE_GET_CONSTANT
@@ -1260,11 +1239,6 @@ void HGraphBuilder::FinishExitWithHardDeoptimization(const char* reason) {
}
-HValue* HGraphBuilder::BuildCheckMap(HValue* obj, Handle<Map> map) {
- return Add<HCheckMaps>(obj, map, top_info());
-}
-
-
HValue* HGraphBuilder::BuildCheckString(HValue* string) {
if (!string->type().IsString()) {
ASSERT(!string->IsConstant() ||
@@ -1314,11 +1288,8 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(
HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap));
HValue* max_capacity = AddUncasted<HAdd>(current_capacity, max_gap);
- IfBuilder key_checker(this);
- key_checker.If<HCompareNumericAndBranch>(key, max_capacity, Token::LT);
- key_checker.Then();
- key_checker.ElseDeopt("Key out of capacity range");
- key_checker.End();
+
+ Add<HBoundsCheck>(key, max_capacity);
HValue* new_capacity = BuildNewElementsCapacity(key);
HValue* new_elements = BuildGrowElementsCapacity(object, elements,
@@ -1794,7 +1765,8 @@ HValue* HGraphBuilder::BuildAddStringLengths(HValue* left_length,
HValue* right_length) {
// Compute the combined string length and check against max string length.
HValue* length = AddUncasted<HAdd>(left_length, right_length);
- HValue* max_length = Add<HConstant>(String::kMaxLength);
+ // Check that length <= kMaxLength <=> length < MaxLength + 1.
+ HValue* max_length = Add<HConstant>(String::kMaxLength + 1);
Add<HBoundsCheck>(length, max_length);
return length;
}
@@ -2167,13 +2139,13 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
if (access_type == STORE && (fast_elements || fast_smi_only_elements) &&
store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
HCheckMaps* check_cow_map = Add<HCheckMaps>(
- elements, isolate()->factory()->fixed_array_map(), top_info());
+ elements, isolate()->factory()->fixed_array_map());
check_cow_map->ClearDependsOnFlag(kElementsKind);
}
HInstruction* length = NULL;
if (is_js_array) {
length = Add<HLoadNamedField>(
- checked_object, static_cast<HValue*>(NULL),
+ checked_object->ActualValue(), checked_object,
HObjectAccess::ForArrayLength(elements_kind));
} else {
length = AddLoadFixedArrayLength(elements);
@@ -2241,7 +2213,7 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
elements_kind, length);
} else {
HCheckMaps* check_cow_map = Add<HCheckMaps>(
- elements, isolate()->factory()->fixed_array_map(), top_info());
+ elements, isolate()->factory()->fixed_array_map());
check_cow_map->ClearDependsOnFlag(kElementsKind);
}
}
@@ -2620,6 +2592,15 @@ HValue* HGraphBuilder::BuildCloneShallowArray(HValue* boilerplate,
}
if (length > 0) {
+ // We have to initialize the elements pointer if allocation folding is
+ // turned off.
+ if (!FLAG_use_gvn || !FLAG_use_allocation_folding) {
+ HConstant* empty_fixed_array = Add<HConstant>(
+ isolate()->factory()->empty_fixed_array());
+ Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
+ empty_fixed_array, INITIALIZING_STORE);
+ }
+
HValue* boilerplate_elements = AddLoadElements(boilerplate);
HValue* object_elements;
if (IsFastDoubleElementsKind(kind)) {
@@ -2700,7 +2681,7 @@ void HGraphBuilder::BuildCompareNil(
// the monomorphic map when the code is used as a template to generate a
// new IC. For optimized functions, there is no sentinel map, the map
// emitted below is the actual monomorphic map.
- BuildCheckMap(value, type->Classes().Current());
+ Add<HCheckMaps>(value, type->Classes().Current());
} else {
if_nil.Deopt("Too many undetectable types");
}
@@ -3090,8 +3071,7 @@ HGraph::HGraph(CompilationInfo* info)
inlined_functions_(5, info->zone()) {
if (info->IsStub()) {
HydrogenCodeStub* stub = info->code_stub();
- CodeStubInterfaceDescriptor* descriptor =
- stub->GetInterfaceDescriptor(isolate_);
+ CodeStubInterfaceDescriptor* descriptor = stub->GetInterfaceDescriptor();
start_environment_ =
new(zone_) HEnvironment(zone_, descriptor->environment_length());
} else {
@@ -4864,7 +4844,7 @@ HOptimizedGraphBuilder::GlobalPropertyAccess
return kUseGeneric;
}
Handle<GlobalObject> global(current_info()->global_object());
- global->Lookup(*var->name(), lookup);
+ global->Lookup(var->name(), lookup);
if (!lookup->IsNormal() ||
(access_type == STORE && lookup->IsReadOnly()) ||
lookup->holder() != *global) {
@@ -4924,11 +4904,11 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
Handle<GlobalObject> global(current_info()->global_object());
Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
if (cell->type()->IsConstant()) {
- cell->AddDependentCompilationInfo(top_info());
- Handle<Object> constant_object = cell->type()->AsConstant();
+ PropertyCell::AddDependentCompilationInfo(cell, top_info());
+ Handle<Object> constant_object = cell->type()->AsConstant()->Value();
if (constant_object->IsConsString()) {
constant_object =
- FlattenGetString(Handle<String>::cast(constant_object));
+ String::Flatten(Handle<String>::cast(constant_object));
}
HConstant* constant = New<HConstant>(constant_object);
return ast_context()->ReturnInstruction(constant, expr->id());
@@ -4998,7 +4978,7 @@ void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
static bool CanInlinePropertyAccess(Type* type) {
if (type->Is(Type::NumberOrString())) return true;
if (!type->IsClass()) return false;
- Handle<Map> map = type->AsClass();
+ Handle<Map> map = type->AsClass()->Map();
return map->IsJSObjectMap() &&
!map->is_dictionary_map() &&
!map->has_named_interceptor();
@@ -5011,9 +4991,9 @@ static bool CanInlinePropertyAccess(Type* type) {
static bool IsFastLiteral(Handle<JSObject> boilerplate,
int max_depth,
int* max_properties) {
- if (boilerplate->map()->is_deprecated()) {
- Handle<Object> result = JSObject::TryMigrateInstance(boilerplate);
- if (result.is_null()) return false;
+ if (boilerplate->map()->is_deprecated() &&
+ !JSObject::TryMigrateInstance(boilerplate)) {
+ return false;
}
ASSERT(max_depth >= 0 && *max_properties >= 0);
@@ -5153,7 +5133,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
} else {
PropertyAccessInfo info(this, STORE, ToType(map), name);
if (info.CanAccessMonomorphic()) {
- HValue* checked_literal = BuildCheckMap(literal, map);
+ HValue* checked_literal = Add<HCheckMaps>(literal, map);
ASSERT(!info.lookup()->IsPropertyCallbacks());
store = BuildMonomorphicAccess(
&info, literal, checked_literal, value,
@@ -5212,11 +5192,12 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
Handle<JSObject> boilerplate_object;
if (literals_cell->IsUndefined()) {
uninitialized = true;
- Handle<Object> raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate(
- isolate(), literals, expr->constant_elements());
- if (raw_boilerplate.is_null()) {
- return Bailout(kArrayBoilerplateCreationFailed);
- }
+ Handle<Object> raw_boilerplate;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate(), raw_boilerplate,
+ Runtime::CreateArrayLiteralBoilerplate(
+ isolate(), literals, expr->constant_elements()),
+ Bailout(kArrayBoilerplateCreationFailed));
boilerplate_object = Handle<JSObject>::cast(raw_boilerplate);
AllocationSiteCreationContext creation_context(isolate());
@@ -5279,7 +5260,7 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
// De-opt if elements kind changed from boilerplate_elements_kind.
Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate());
- literal = Add<HCheckMaps>(literal, map, top_info());
+ literal = Add<HCheckMaps>(literal, map);
}
// The array is expected in the bailout environment during computation
@@ -5332,13 +5313,31 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
HCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object,
Handle<Map> map) {
BuildCheckHeapObject(object);
- return Add<HCheckMaps>(object, map, top_info());
+ return Add<HCheckMaps>(object, map);
}
HInstruction* HOptimizedGraphBuilder::BuildLoadNamedField(
PropertyAccessInfo* info,
HValue* checked_object) {
+ // See if this is a load for an immutable property
+ if (checked_object->ActualValue()->IsConstant() &&
+ info->lookup()->IsCacheable() &&
+ info->lookup()->IsReadOnly() && info->lookup()->IsDontDelete()) {
+ Handle<Object> object(
+ HConstant::cast(checked_object->ActualValue())->handle(isolate()));
+
+ if (object->IsJSObject()) {
+ LookupResult lookup(isolate());
+ Handle<JSObject>::cast(object)->Lookup(info->name(), &lookup);
+ Handle<Object> value(lookup.GetLazyValue(), isolate());
+
+ if (!value->IsTheHole()) {
+ return New<HConstant>(value);
+ }
+ }
+ }
+
HObjectAccess access = info->access();
if (access.representation().IsDouble()) {
// Load the heap number.
@@ -5349,8 +5348,24 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedField(
// Load the double value from it.
access = HObjectAccess::ForHeapNumberValue();
}
+
+ SmallMapList* map_list = info->field_maps();
+ if (map_list->length() == 0) {
+ return New<HLoadNamedField>(checked_object, checked_object, access);
+ }
+
+ UniqueSet<Map>* maps = new(zone()) UniqueSet<Map>(map_list->length(), zone());
+ for (int i = 0; i < map_list->length(); ++i) {
+ Handle<Map> map = map_list->at(i);
+ maps->Add(Unique<Map>::CreateImmovable(map), zone());
+ // TODO(bmeurer): Get rid of this shit!
+ if (map->CanTransition()) {
+ Map::AddDependentCompilationInfo(
+ map, DependentCode::kPrototypeCheckGroup, top_info());
+ }
+ }
return New<HLoadNamedField>(
- checked_object, static_cast<HValue*>(NULL), access);
+ checked_object, checked_object, access, maps, info->field_type());
}
@@ -5360,8 +5375,7 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
HValue* value) {
bool transition_to_field = info->lookup()->IsTransition();
// TODO(verwaest): Move this logic into PropertyAccessInfo.
- HObjectAccess field_access = HObjectAccess::ForField(
- info->map(), info->lookup(), info->name());
+ HObjectAccess field_access = info->access();
HStoreNamedField *instr;
if (field_access.representation().IsDouble()) {
@@ -5395,6 +5409,18 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
value, STORE_TO_INITIALIZED_ENTRY);
}
} else {
+ if (!info->field_maps()->is_empty()) {
+ ASSERT(field_access.representation().IsHeapObject());
+ BuildCheckHeapObject(value);
+ value = Add<HCheckMaps>(value, info->field_maps());
+
+ // TODO(bmeurer): This is a dirty hack to avoid repeating the smi check
+ // that was already performed by the HCheckHeapObject above in the
+ // HStoreNamedField below. We should really do this right instead and
+ // make Crankshaft aware of Representation::HeapObject().
+ field_access = field_access.WithRepresentation(Representation::Tagged());
+ }
+
// This is a normal store.
instr = New<HStoreNamedField>(
checked_object->ActualValue(), field_access, value,
@@ -5402,9 +5428,9 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
}
if (transition_to_field) {
- HConstant* transition_constant = Add<HConstant>(info->transition());
- instr->SetTransition(transition_constant, top_info());
- instr->SetChangesFlag(kMaps);
+ Handle<Map> transition(info->transition());
+ ASSERT(!transition->is_deprecated());
+ instr->SetTransition(Add<HConstant>(transition));
}
return instr;
}
@@ -5458,7 +5484,27 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible(
}
if (info->access_.offset() != access_.offset()) return false;
if (info->access_.IsInobject() != access_.IsInobject()) return false;
+ if (IsLoad()) {
+ if (field_maps_.is_empty()) {
+ info->field_maps_.Clear();
+ } else if (!info->field_maps_.is_empty()) {
+ for (int i = 0; i < field_maps_.length(); ++i) {
+ info->field_maps_.AddMapIfMissing(field_maps_.at(i), info->zone());
+ }
+ info->field_maps_.Sort();
+ }
+ } else {
+ // We can only merge stores that agree on their field maps. The comparison
+ // below is safe, since we keep the field maps sorted.
+ if (field_maps_.length() != info->field_maps_.length()) return false;
+ for (int i = 0; i < field_maps_.length(); ++i) {
+ if (!field_maps_.at(i).is_identical_to(info->field_maps_.at(i))) {
+ return false;
+ }
+ }
+ }
info->GeneralizeRepresentation(r);
+ info->field_type_ = info->field_type_.Combine(field_type_);
return true;
}
@@ -5477,7 +5523,11 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) {
}
if (lookup_.IsField()) {
+ // Construct the object field access.
access_ = HObjectAccess::ForField(map, &lookup_, name_);
+
+ // Load field map for heap objects.
+ LoadFieldMaps(map);
} else if (lookup_.IsPropertyCallbacks()) {
Handle<Object> callback(lookup_.GetValueFromMap(*map), isolate());
if (!callback->IsAccessorPair()) return false;
@@ -5488,16 +5538,11 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) {
Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor));
if (accessor->shared()->IsApiFunction()) {
CallOptimization call_optimization(accessor);
- if (!call_optimization.is_simple_api_call()) return false;
- CallOptimization::HolderLookup holder_lookup;
- api_holder_ = call_optimization.LookupHolderOfExpectedType(
- map, &holder_lookup);
- switch (holder_lookup) {
- case CallOptimization::kHolderNotFound:
- return false;
- case CallOptimization::kHolderIsReceiver:
- case CallOptimization::kHolderFound:
- break;
+ if (call_optimization.is_simple_api_call()) {
+ CallOptimization::HolderLookup holder_lookup;
+ Handle<Map> receiver_map = this->map();
+ api_holder_ = call_optimization.LookupHolderOfExpectedType(
+ receiver_map, &holder_lookup);
}
}
accessor_ = accessor;
@@ -5509,6 +5554,56 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) {
}
+void HOptimizedGraphBuilder::PropertyAccessInfo::LoadFieldMaps(
+ Handle<Map> map) {
+ // Clear any previously collected field maps/type.
+ field_maps_.Clear();
+ field_type_ = HType::Tagged();
+
+ // Figure out the field type from the accessor map.
+ Handle<HeapType> field_type(lookup_.GetFieldTypeFromMap(*map), isolate());
+
+ // Collect the (stable) maps from the field type.
+ int num_field_maps = field_type->NumClasses();
+ if (num_field_maps == 0) return;
+ ASSERT(access_.representation().IsHeapObject());
+ field_maps_.Reserve(num_field_maps, zone());
+ HeapType::Iterator<Map> it = field_type->Classes();
+ while (!it.Done()) {
+ Handle<Map> field_map = it.Current();
+ if (!field_map->is_stable()) {
+ field_maps_.Clear();
+ return;
+ }
+ field_maps_.Add(field_map, zone());
+ it.Advance();
+ }
+ field_maps_.Sort();
+ ASSERT_EQ(num_field_maps, field_maps_.length());
+
+ // Determine field HType from field HeapType.
+ if (field_type->Is(HeapType::Number())) {
+ field_type_ = HType::HeapNumber();
+ } else if (field_type->Is(HeapType::String())) {
+ field_type_ = HType::String();
+ } else if (field_type->Is(HeapType::Boolean())) {
+ field_type_ = HType::Boolean();
+ } else if (field_type->Is(HeapType::Array())) {
+ field_type_ = HType::JSArray();
+ } else if (field_type->Is(HeapType::Object())) {
+ field_type_ = HType::JSObject();
+ } else if (field_type->Is(HeapType::Null()) ||
+ field_type->Is(HeapType::Undefined())) {
+ field_type_ = HType::NonPrimitive();
+ }
+
+ // Add dependency on the map that introduced the field.
+ Map::AddDependentCompilationInfo(
+ handle(lookup_.GetFieldOwnerFromMap(*map), isolate()),
+ DependentCode::kFieldTypeGroup, top_info());
+}
+
+
bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() {
Handle<Map> map = this->map();
@@ -5545,6 +5640,11 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() {
Handle<Map> map = this->map();
map->LookupTransition(NULL, *name_, &lookup_);
if (lookup_.IsTransitionToField() && map->unused_property_fields() > 0) {
+ // Construct the object field access.
+ access_ = HObjectAccess::ForField(map, &lookup_, name_);
+
+ // Load field map for heap objects.
+ LoadFieldMaps(transition());
return true;
}
return false;
@@ -5652,7 +5752,7 @@ HInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess(
? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id)
: TryInlineSetter(
info->accessor(), info->map(), ast_id, return_id, value);
- if (success) return NULL;
+ if (success || HasStackOverflow()) return NULL;
}
PushArgumentsFromEnvironment(argument_count);
@@ -5899,7 +5999,7 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
Handle<GlobalObject> global(current_info()->global_object());
Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
if (cell->type()->IsConstant()) {
- Handle<Object> constant = cell->type()->AsConstant();
+ Handle<Object> constant = cell->type()->AsConstant()->Value();
if (value->IsConstant()) {
HConstant* c_value = HConstant::cast(value);
if (!constant.is_identical_to(c_value->handle(isolate()))) {
@@ -6284,8 +6384,7 @@ HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess(
Handle<Map> map,
PropertyAccessType access_type,
KeyedAccessStoreMode store_mode) {
- HCheckMaps* checked_object = Add<HCheckMaps>(object, map, top_info(),
- dependency);
+ HCheckMaps* checked_object = Add<HCheckMaps>(object, map, dependency);
if (dependency) {
checked_object->ClearDependsOnFlag(kElementsKind);
}
@@ -6764,19 +6863,9 @@ void HOptimizedGraphBuilder::VisitProperty(Property* expr) {
}
-HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant,
- CompilationInfo* info) {
- HConstant* constant_value = New<HConstant>(constant);
-
- if (constant->map()->CanOmitMapChecks()) {
- constant->map()->AddDependentCompilationInfo(
- DependentCode::kPrototypeCheckGroup, info);
- return constant_value;
- }
-
- AddInstruction(constant_value);
- HCheckMaps* check =
- Add<HCheckMaps>(constant_value, handle(constant->map()), info);
+HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant) {
+ HCheckMaps* check = Add<HCheckMaps>(
+ Add<HConstant>(constant), handle(constant->map()));
check->ClearDependsOnFlag(kElementsKind);
return check;
}
@@ -6784,14 +6873,14 @@ HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant,
HInstruction* HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype,
Handle<JSObject> holder) {
- while (!prototype.is_identical_to(holder)) {
- BuildConstantMapCheck(prototype, top_info());
- prototype = handle(JSObject::cast(prototype->GetPrototype()));
+ while (holder.is_null() || !prototype.is_identical_to(holder)) {
+ BuildConstantMapCheck(prototype);
+ Object* next_prototype = prototype->GetPrototype();
+ if (next_prototype->IsNull()) return NULL;
+ CHECK(next_prototype->IsJSObject());
+ prototype = handle(JSObject::cast(next_prototype));
}
-
- HInstruction* checked_object = BuildConstantMapCheck(prototype, top_info());
- if (!checked_object->IsLinked()) AddInstruction(checked_object);
- return checked_object;
+ return BuildConstantMapCheck(prototype);
}
@@ -6861,13 +6950,36 @@ HInstruction* HOptimizedGraphBuilder::BuildCallConstantFunction(
}
+class FunctionSorter {
+ public:
+ FunctionSorter(int index = 0, int ticks = 0, int size = 0)
+ : index_(index), ticks_(ticks), size_(size) { }
+
+ int index() const { return index_; }
+ int ticks() const { return ticks_; }
+ int size() const { return size_; }
+
+ private:
+ int index_;
+ int ticks_;
+ int size_;
+};
+
+
+inline bool operator<(const FunctionSorter& lhs, const FunctionSorter& rhs) {
+ int diff = lhs.ticks() - rhs.ticks();
+ if (diff != 0) return diff > 0;
+ return lhs.size() < rhs.size();
+}
+
+
void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
Call* expr,
HValue* receiver,
SmallMapList* types,
Handle<String> name) {
int argument_count = expr->arguments()->length() + 1; // Includes receiver.
- int order[kMaxCallPolymorphism];
+ FunctionSorter order[kMaxCallPolymorphism];
bool handle_smi = false;
bool handled_string = false;
@@ -6889,17 +7001,20 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
handle_smi = true;
}
expr->set_target(target);
- order[ordered_functions++] = i;
+ order[ordered_functions++] = FunctionSorter(
+ i, target->shared()->profiler_ticks(), InliningAstSize(target));
}
}
+ std::sort(order, order + ordered_functions);
+
HBasicBlock* number_block = NULL;
HBasicBlock* join = NULL;
handled_string = false;
int count = 0;
for (int fn = 0; fn < ordered_functions; ++fn) {
- int i = order[fn];
+ int i = order[fn].index();
PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name);
if (info.type()->Is(Type::String())) {
if (handled_string) continue;
@@ -7071,6 +7186,11 @@ int HOptimizedGraphBuilder::InliningAstSize(Handle<JSFunction> target) {
return target_shared->inline_builtin() ? 0 : kNotInlinable;
}
+ if (target_shared->IsApiFunction()) {
+ TraceInline(target, caller, "target is api function");
+ return kNotInlinable;
+ }
+
// Do a quick check on source code length to avoid parsing large
// inlining candidates.
if (target_shared->SourceSize() >
@@ -7219,6 +7339,7 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
target_shared->set_scope_info(*target_scope_info);
}
target_shared->EnableDeoptimizationSupport(*target_info.code());
+ target_shared->set_feedback_vector(*target_info.feedback_vector());
Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG,
&target_info,
target_shared);
@@ -7252,8 +7373,6 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
HConstant* context = Add<HConstant>(Handle<Context>(target->context()));
inner_env->BindContext(context);
- Add<HSimulate>(return_id);
- current_block()->UpdateEnvironment(inner_env);
HArgumentsObject* arguments_object = NULL;
// If the function uses arguments object create and bind one, also copy
@@ -7269,8 +7388,17 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
}
}
+ // Capture the state before invoking the inlined function for deopt in the
+ // inlined function. This simulate has no bailout-id since it's not directly
+ // reachable for deopt, and is only used to capture the state. If the simulate
+ // becomes reachable by merging, the ast id of the simulate merged into it is
+ // adopted.
+ Add<HSimulate>(BailoutId::None());
+
+ current_block()->UpdateEnvironment(inner_env);
+
HEnterInlined* enter_inlined =
- Add<HEnterInlined>(target, arguments_count, function,
+ Add<HEnterInlined>(return_id, target, arguments_count, function,
function_state()->inlining_kind(),
function->scope()->arguments(),
arguments_object);
@@ -7596,6 +7724,8 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
ElementsKind elements_kind = receiver_map->elements_kind();
if (!IsFastElementsKind(elements_kind)) return false;
+ if (receiver_map->is_observed()) return false;
+ ASSERT(receiver_map->is_extensible());
Drop(expr->arguments()->length());
HValue* result;
@@ -7658,32 +7788,51 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
ElementsKind elements_kind = receiver_map->elements_kind();
if (!IsFastElementsKind(elements_kind)) return false;
-
- HValue* op_vals[] = {
- context(),
- // Receiver.
- environment()->ExpressionStackAt(expr->arguments()->length())
- };
+ if (receiver_map->is_observed()) return false;
+ ASSERT(receiver_map->is_extensible());
+
+ // If there may be elements accessors in the prototype chain, the fast
+ // inlined version can't be used.
+ if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false;
+ // If there currently can be no elements accessors on the prototype chain,
+ // it doesn't mean that there won't be any later. Install a full prototype
+ // chain check to trap element accessors being installed on the prototype
+ // chain, which would cause elements to go to dictionary mode and result
+ // in a map change.
+ Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
+ BuildCheckPrototypeMaps(prototype, Handle<JSObject>());
const int argc = expr->arguments()->length();
- // Includes receiver.
- PushArgumentsFromEnvironment(argc + 1);
+ if (argc != 1) return false;
- CallInterfaceDescriptor* descriptor =
- isolate()->call_descriptor(Isolate::CallHandler);
+ HValue* value_to_push = Pop();
+ HValue* array = Pop();
+ Drop(1); // Drop function.
- ArrayPushStub stub(receiver_map->elements_kind(), argc);
- Handle<Code> code = stub.GetCode(isolate());
- HConstant* code_value = Add<HConstant>(code);
+ HInstruction* new_size = NULL;
+ HValue* length = NULL;
- ASSERT((sizeof(op_vals) / kPointerSize) ==
- descriptor->environment_length());
+ {
+ NoObservableSideEffectsScope scope(this);
- HInstruction* call = New<HCallWithDescriptor>(
- code_value, argc + 1, descriptor,
- Vector<HValue*>(op_vals, descriptor->environment_length()));
- Drop(1); // Drop function.
- ast_context()->ReturnInstruction(call, expr->id());
+ length = Add<HLoadNamedField>(array, static_cast<HValue*>(NULL),
+ HObjectAccess::ForArrayLength(elements_kind));
+
+ new_size = AddUncasted<HAdd>(length, graph()->GetConstant1());
+
+ bool is_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
+ BuildUncheckedMonomorphicElementAccess(array, length,
+ value_to_push, is_array,
+ elements_kind, STORE,
+ NEVER_RETURN_HOLE,
+ STORE_AND_GROW_NO_TRANSITION);
+
+ if (!ast_context()->IsEffect()) Push(new_size);
+ Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
+ if (!ast_context()->IsEffect()) Drop(1);
+ }
+
+ ast_context()->ReturnValue(new_size);
return true;
}
default:
@@ -7763,7 +7912,7 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<JSFunction> function,
if (call_type == kCallApiFunction) {
// Cannot embed a direct reference to the global proxy map
// as it maybe dropped on deserialization.
- CHECK(!Serializer::enabled());
+ CHECK(!Serializer::enabled(isolate()));
ASSERT_EQ(0, receiver_maps->length());
receiver_maps->Add(handle(
function->context()->global_object()->global_receiver()->map()),
@@ -7855,8 +8004,8 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<JSFunction> function,
CallInterfaceDescriptor* descriptor =
isolate()->call_descriptor(Isolate::ApiFunctionCall);
- CallApiFunctionStub stub(is_store, call_data_is_undefined, argc);
- Handle<Code> code = stub.GetCode(isolate());
+ CallApiFunctionStub stub(isolate(), is_store, call_data_is_undefined, argc);
+ Handle<Code> code = stub.GetCode();
HConstant* code_value = Add<HConstant>(code);
ASSERT((sizeof(op_vals) / kPointerSize) ==
@@ -7950,7 +8099,7 @@ HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function,
if (shared->strict_mode() == SLOPPY && !shared->native()) {
// Cannot embed a direct reference to the global proxy
// as is it dropped on deserialization.
- CHECK(!Serializer::enabled());
+ CHECK(!Serializer::enabled(isolate()));
Handle<JSObject> global_receiver(
target->context()->global_object()->global_receiver());
return Add<HConstant>(global_receiver);
@@ -8510,6 +8659,10 @@ HValue* HOptimizedGraphBuilder::BuildAllocateExternalElements(
HValue* buffer, HValue* byte_offset, HValue* length) {
Handle<Map> external_array_map(
isolate()->heap()->MapForExternalArrayType(array_type));
+
+ // The HForceRepresentation is to prevent possible deopt on int-smi
+ // conversion after allocation but before the new object fields are set.
+ length = AddUncasted<HForceRepresentation>(length, Representation::Smi());
HValue* elements =
Add<HAllocate>(
Add<HConstant>(ExternalArray::kAlignedSize),
@@ -8518,6 +8671,8 @@ HValue* HOptimizedGraphBuilder::BuildAllocateExternalElements(
external_array_map->instance_type());
AddStoreMapConstant(elements, external_array_map);
+ Add<HStoreNamedField>(elements,
+ HObjectAccess::ForFixedArrayLength(), length);
HValue* backing_store = Add<HLoadNamedField>(
buffer, static_cast<HValue*>(NULL),
@@ -8535,13 +8690,10 @@ HValue* HOptimizedGraphBuilder::BuildAllocateExternalElements(
typed_array_start = external_pointer;
}
-
Add<HStoreNamedField>(elements,
HObjectAccess::ForExternalArrayExternalPointer(),
typed_array_start);
- Add<HStoreNamedField>(elements,
- HObjectAccess::ForFixedArrayLength(), length);
return elements;
}
@@ -8565,6 +8717,9 @@ HValue* HOptimizedGraphBuilder::BuildAllocateFixedTypedArray(
total_size->ClearFlag(HValue::kCanOverflow);
}
+ // The HForceRepresentation is to prevent possible deopt on int-smi
+ // conversion after allocation but before the new object fields are set.
+ length = AddUncasted<HForceRepresentation>(length, Representation::Smi());
Handle<Map> fixed_typed_array_map(
isolate()->heap()->MapForFixedTypedArray(array_type));
HValue* elements =
@@ -8576,6 +8731,7 @@ HValue* HOptimizedGraphBuilder::BuildAllocateFixedTypedArray(
Add<HStoreNamedField>(elements,
HObjectAccess::ForFixedArrayLength(),
length);
+
HValue* filler = Add<HConstant>(static_cast<int32_t>(0));
{
@@ -8588,8 +8744,6 @@ HValue* HOptimizedGraphBuilder::BuildAllocateFixedTypedArray(
builder.EndBody();
}
- Add<HStoreNamedField>(
- elements, HObjectAccess::ForFixedArrayLength(), length);
return elements;
}
@@ -8725,6 +8879,58 @@ void HOptimizedGraphBuilder::GenerateTypedArrayMaxSizeInHeap(
}
+void HOptimizedGraphBuilder::GenerateArrayBufferGetByteLength(
+ CallRuntime* expr) {
+ ASSERT(expr->arguments()->length() == 1);
+ CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
+ HValue* buffer = Pop();
+ HInstruction* result = New<HLoadNamedField>(
+ buffer,
+ static_cast<HValue*>(NULL),
+ HObjectAccess::ForJSArrayBufferByteLength());
+ return ast_context()->ReturnInstruction(result, expr->id());
+}
+
+
+void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteLength(
+ CallRuntime* expr) {
+ ASSERT(expr->arguments()->length() == 1);
+ CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
+ HValue* buffer = Pop();
+ HInstruction* result = New<HLoadNamedField>(
+ buffer,
+ static_cast<HValue*>(NULL),
+ HObjectAccess::ForJSArrayBufferViewByteLength());
+ return ast_context()->ReturnInstruction(result, expr->id());
+}
+
+
+void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteOffset(
+ CallRuntime* expr) {
+ ASSERT(expr->arguments()->length() == 1);
+ CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
+ HValue* buffer = Pop();
+ HInstruction* result = New<HLoadNamedField>(
+ buffer,
+ static_cast<HValue*>(NULL),
+ HObjectAccess::ForJSArrayBufferViewByteOffset());
+ return ast_context()->ReturnInstruction(result, expr->id());
+}
+
+
+void HOptimizedGraphBuilder::GenerateTypedArrayGetLength(
+ CallRuntime* expr) {
+ ASSERT(expr->arguments()->length() == 1);
+ CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
+ HValue* buffer = Pop();
+ HInstruction* result = New<HLoadNamedField>(
+ buffer,
+ static_cast<HValue*>(NULL),
+ HObjectAccess::ForJSTypedArrayLength());
+ return ast_context()->ReturnInstruction(result, expr->id());
+}
+
+
void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
@@ -9686,7 +9892,7 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
Handle<String> name = proxy->name();
Handle<GlobalObject> global(current_info()->global_object());
LookupResult lookup(isolate());
- global->Lookup(*name, &lookup);
+ global->Lookup(name, &lookup);
if (lookup.IsNormal() && lookup.GetValue()->IsJSFunction()) {
Handle<JSFunction> candidate(JSFunction::cast(lookup.GetValue()));
// If the function is in new space we assume it's more likely to
@@ -9760,11 +9966,22 @@ HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction(
if (combined_type->Is(Type::Receiver())) {
if (Token::IsEqualityOp(op)) {
+ // HCompareObjectEqAndBranch can only deal with object, so
+ // exclude numbers.
+ if ((left->IsConstant() &&
+ HConstant::cast(left)->HasNumberValue()) ||
+ (right->IsConstant() &&
+ HConstant::cast(right)->HasNumberValue())) {
+ Add<HDeoptimize>("Type mismatch between feedback and constant",
+ Deoptimizer::SOFT);
+ // The caller expects a branch instruction, so make it happy.
+ return New<HBranch>(graph()->GetConstantTrue());
+ }
// Can we get away with map check and not instance type check?
HValue* operand_to_check =
left->block()->block_id() < right->block()->block_id() ? left : right;
if (combined_type->IsClass()) {
- Handle<Map> map = combined_type->AsClass();
+ Handle<Map> map = combined_type->AsClass()->Map();
AddCheckMap(operand_to_check, map);
HCompareObjectEqAndBranch* result =
New<HCompareObjectEqAndBranch>(left, right);
@@ -9787,6 +10004,17 @@ HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction(
}
} else if (combined_type->Is(Type::InternalizedString()) &&
Token::IsEqualityOp(op)) {
+ // If we have a constant argument, it should be consistent with the type
+ // feedback (otherwise we fail assertions in HCompareObjectEqAndBranch).
+ if ((left->IsConstant() &&
+ !HConstant::cast(left)->HasInternalizedStringValue()) ||
+ (right->IsConstant() &&
+ !HConstant::cast(right)->HasInternalizedStringValue())) {
+ Add<HDeoptimize>("Type mismatch between feedback and constant",
+ Deoptimizer::SOFT);
+ // The caller expects a branch instruction, so make it happy.
+ return New<HBranch>(graph()->GetConstantTrue());
+ }
BuildCheckHeapObject(left);
Add<HCheckInstanceType>(left, HCheckInstanceType::IS_INTERNALIZED_STRING);
BuildCheckHeapObject(right);
@@ -10602,12 +10830,6 @@ void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) {
}
-void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) {
- // %_Log is ignored in optimized code.
- return ast_context()->ReturnValue(graph()->GetConstantUndefined());
-}
-
-
// Fast support for StringAdd.
void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) {
ASSERT_EQ(2, call->arguments()->length());
@@ -10817,6 +11039,14 @@ void HOptimizedGraphBuilder::GenerateDebugBreakInOptimizedCode(
}
+void HOptimizedGraphBuilder::GenerateDebugCallbackSupportsStepping(
+ CallRuntime* call) {
+ ASSERT(call->arguments()->length() == 1);
+ // Debugging is not supported in optimized code.
+ return ast_context()->ReturnValue(graph()->GetConstantFalse());
+}
+
+
#undef CHECK_BAILOUT
#undef CHECK_ALIVE
diff --git a/deps/v8/src/hydrogen.h b/deps/v8/src/hydrogen.h
index 6d81307e2c..d20a81771e 100644
--- a/deps/v8/src/hydrogen.h
+++ b/deps/v8/src/hydrogen.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_H_
#define V8_HYDROGEN_H_
@@ -438,9 +415,11 @@ class HGraph V8_FINAL : public ZoneObject {
void MarkDependsOnEmptyArrayProtoElements() {
// Add map dependency if not already added.
if (depends_on_empty_array_proto_elements_) return;
- isolate()->initial_object_prototype()->map()->AddDependentCompilationInfo(
+ Map::AddDependentCompilationInfo(
+ handle(isolate()->initial_object_prototype()->map()),
DependentCode::kElementsCantBeAddedGroup, info());
- isolate()->initial_array_prototype()->map()->AddDependentCompilationInfo(
+ Map::AddDependentCompilationInfo(
+ handle(isolate()->initial_array_prototype()->map()),
DependentCode::kElementsCantBeAddedGroup, info());
depends_on_empty_array_proto_elements_ = true;
}
@@ -1319,7 +1298,6 @@ class HGraphBuilder {
HBasicBlock* CreateLoopHeaderBlock();
HValue* BuildCheckHeapObject(HValue* object);
- HValue* BuildCheckMap(HValue* obj, Handle<Map> map);
HValue* BuildCheckString(HValue* string);
HValue* BuildWrapReceiver(HValue* object, HValue* function);
@@ -1802,8 +1780,7 @@ class HGraphBuilder {
HValue* previous_object_size,
HValue* payload);
- HInstruction* BuildConstantMapCheck(Handle<JSObject> constant,
- CompilationInfo* info);
+ HInstruction* BuildConstantMapCheck(Handle<JSObject> constant);
HInstruction* BuildCheckPrototypeMaps(Handle<JSObject> prototype,
Handle<JSObject> holder);
@@ -2349,6 +2326,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
access_type_(access_type),
type_(type),
name_(name),
+ field_type_(HType::Tagged()),
access_(HObjectAccess::ForMap()) { }
// Checkes whether this PropertyAccessInfo can be handled as a monomorphic
@@ -2378,7 +2356,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
context = context->native_context();
return handle(context->string_function()->initial_map());
} else {
- return type_->AsClass();
+ return type_->AsClass()->Map();
}
}
Type* type() const { return type_; }
@@ -2393,10 +2371,10 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
int offset;
if (Accessors::IsJSObjectFieldAccessor<Type>(type_, name_, &offset)) {
if (type_->Is(Type::String())) {
- ASSERT(name_->Equals(isolate()->heap()->length_string()));
+ ASSERT(String::Equals(isolate()->factory()->length_string(), name_));
*access = HObjectAccess::ForStringLength();
} else if (type_->Is(Type::Array())) {
- ASSERT(name_->Equals(isolate()->heap()->length_string()));
+ ASSERT(String::Equals(isolate()->factory()->length_string(), name_));
*access = HObjectAccess::ForArrayLength(map()->elements_kind());
} else {
*access = HObjectAccess::ForMapAndOffset(map(), offset);
@@ -2414,14 +2392,19 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
Handle<JSFunction> accessor() { return accessor_; }
Handle<Object> constant() { return constant_; }
Handle<Map> transition() { return handle(lookup_.GetTransitionTarget()); }
+ SmallMapList* field_maps() { return &field_maps_; }
+ HType field_type() const { return field_type_; }
HObjectAccess access() { return access_; }
private:
Type* ToType(Handle<Map> map) { return builder_->ToType(map); }
+ Zone* zone() { return builder_->zone(); }
Isolate* isolate() { return lookup_.isolate(); }
+ CompilationInfo* top_info() { return builder_->top_info(); }
CompilationInfo* current_info() { return builder_->current_info(); }
bool LoadResult(Handle<Map> map);
+ void LoadFieldMaps(Handle<Map> map);
bool LookupDescriptor();
bool LookupInPrototypes();
bool IsCompatible(PropertyAccessInfo* other);
@@ -2440,6 +2423,8 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
Handle<JSFunction> accessor_;
Handle<JSObject> api_holder_;
Handle<Object> constant_;
+ SmallMapList field_maps_;
+ HType field_type_;
HObjectAccess access_;
};
diff --git a/deps/v8/src/i18n.cc b/deps/v8/src/i18n.cc
index d5ea77dbdf..2b6b0fb07e 100644
--- a/deps/v8/src/i18n.cc
+++ b/deps/v8/src/i18n.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// limitations under the License.
#include "i18n.h"
@@ -57,12 +34,11 @@ bool ExtractStringSetting(Isolate* isolate,
Handle<JSObject> options,
const char* key,
icu::UnicodeString* setting) {
- Handle<String> str = isolate->factory()->NewStringFromAscii(CStrVector(key));
- MaybeObject* maybe_object = options->GetProperty(*str);
- Object* object;
- if (maybe_object->ToObject(&object) && object->IsString()) {
+ Handle<String> str = isolate->factory()->NewStringFromAsciiChecked(key);
+ Handle<Object> object = Object::GetProperty(options, str).ToHandleChecked();
+ if (object->IsString()) {
v8::String::Utf8Value utf8_string(
- v8::Utils::ToLocal(Handle<String>(String::cast(object))));
+ v8::Utils::ToLocal(Handle<String>::cast(object)));
*setting = icu::UnicodeString::fromUTF8(*utf8_string);
return true;
}
@@ -74,10 +50,9 @@ bool ExtractIntegerSetting(Isolate* isolate,
Handle<JSObject> options,
const char* key,
int32_t* value) {
- Handle<String> str = isolate->factory()->NewStringFromAscii(CStrVector(key));
- MaybeObject* maybe_object = options->GetProperty(*str);
- Object* object;
- if (maybe_object->ToObject(&object) && object->IsNumber()) {
+ Handle<String> str = isolate->factory()->NewStringFromAsciiChecked(key);
+ Handle<Object> object = Object::GetProperty(options, str).ToHandleChecked();
+ if (object->IsNumber()) {
object->ToInt32(value);
return true;
}
@@ -89,10 +64,9 @@ bool ExtractBooleanSetting(Isolate* isolate,
Handle<JSObject> options,
const char* key,
bool* value) {
- Handle<String> str = isolate->factory()->NewStringFromAscii(CStrVector(key));
- MaybeObject* maybe_object = options->GetProperty(*str);
- Object* object;
- if (maybe_object->ToObject(&object) && object->IsBoolean()) {
+ Handle<String> str = isolate->factory()->NewStringFromAsciiChecked(key);
+ Handle<Object> object = Object::GetProperty(options, str).ToHandleChecked();
+ if (object->IsBoolean()) {
*value = object->BooleanValue();
return true;
}
@@ -152,28 +126,29 @@ void SetResolvedDateSettings(Isolate* isolate,
const icu::Locale& icu_locale,
icu::SimpleDateFormat* date_format,
Handle<JSObject> resolved) {
+ Factory* factory = isolate->factory();
UErrorCode status = U_ZERO_ERROR;
icu::UnicodeString pattern;
date_format->toPattern(pattern);
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("pattern")),
- isolate->factory()->NewStringFromTwoByte(
+ factory->NewStringFromStaticAscii("pattern"),
+ factory->NewStringFromTwoByte(
Vector<const uint16_t>(
reinterpret_cast<const uint16_t*>(pattern.getBuffer()),
- pattern.length())),
+ pattern.length())).ToHandleChecked(),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
// Set time zone and calendar.
const icu::Calendar* calendar = date_format->getCalendar();
const char* calendar_name = calendar->getType();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("calendar")),
- isolate->factory()->NewStringFromAscii(CStrVector(calendar_name)),
+ factory->NewStringFromStaticAscii("calendar"),
+ factory->NewStringFromAsciiChecked(calendar_name),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
const icu::TimeZone& tz = calendar->getTimeZone();
icu::UnicodeString time_zone;
@@ -185,21 +160,21 @@ void SetResolvedDateSettings(Isolate* isolate,
if (canonical_time_zone == UNICODE_STRING_SIMPLE("Etc/GMT")) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("timeZone")),
- isolate->factory()->NewStringFromAscii(CStrVector("UTC")),
+ factory->NewStringFromStaticAscii("timeZone"),
+ factory->NewStringFromStaticAscii("UTC"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
} else {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("timeZone")),
- isolate->factory()->NewStringFromTwoByte(
+ factory->NewStringFromStaticAscii("timeZone"),
+ factory->NewStringFromTwoByte(
Vector<const uint16_t>(
reinterpret_cast<const uint16_t*>(
canonical_time_zone.getBuffer()),
- canonical_time_zone.length())),
+ canonical_time_zone.length())).ToHandleChecked(),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
}
}
@@ -213,17 +188,17 @@ void SetResolvedDateSettings(Isolate* isolate,
const char* ns = numbering_system->getName();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
- isolate->factory()->NewStringFromAscii(CStrVector(ns)),
+ factory->NewStringFromStaticAscii("numberingSystem"),
+ factory->NewStringFromAsciiChecked(ns),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
} else {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
- isolate->factory()->undefined_value(),
+ factory->NewStringFromStaticAscii("numberingSystem"),
+ factory->undefined_value(),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
}
delete numbering_system;
@@ -235,18 +210,18 @@ void SetResolvedDateSettings(Isolate* isolate,
if (U_SUCCESS(status)) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector(result)),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromAsciiChecked(result),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
} else {
// This would never happen, since we got the locale from ICU.
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector("und")),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromStaticAscii("und"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
}
}
@@ -379,30 +354,31 @@ void SetResolvedNumberSettings(Isolate* isolate,
const icu::Locale& icu_locale,
icu::DecimalFormat* number_format,
Handle<JSObject> resolved) {
+ Factory* factory = isolate->factory();
icu::UnicodeString pattern;
number_format->toPattern(pattern);
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("pattern")),
- isolate->factory()->NewStringFromTwoByte(
+ factory->NewStringFromStaticAscii("pattern"),
+ factory->NewStringFromTwoByte(
Vector<const uint16_t>(
reinterpret_cast<const uint16_t*>(pattern.getBuffer()),
- pattern.length())),
+ pattern.length())).ToHandleChecked(),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
// Set resolved currency code in options.currency if not empty.
icu::UnicodeString currency(number_format->getCurrency());
if (!currency.isEmpty()) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("currency")),
- isolate->factory()->NewStringFromTwoByte(
+ factory->NewStringFromStaticAscii("currency"),
+ factory->NewStringFromTwoByte(
Vector<const uint16_t>(
reinterpret_cast<const uint16_t*>(currency.getBuffer()),
- currency.length())),
+ currency.length())).ToHandleChecked(),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
}
// Ugly hack. ICU doesn't expose numbering system in any way, so we have
@@ -415,78 +391,67 @@ void SetResolvedNumberSettings(Isolate* isolate,
const char* ns = numbering_system->getName();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
- isolate->factory()->NewStringFromAscii(CStrVector(ns)),
+ factory->NewStringFromStaticAscii("numberingSystem"),
+ factory->NewStringFromAsciiChecked(ns),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
} else {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
- isolate->factory()->undefined_value(),
+ factory->NewStringFromStaticAscii("numberingSystem"),
+ factory->undefined_value(),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
}
delete numbering_system;
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("useGrouping")),
- isolate->factory()->ToBoolean(number_format->isGroupingUsed()),
+ factory->NewStringFromStaticAscii("useGrouping"),
+ factory->ToBoolean(number_format->isGroupingUsed()),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(
- CStrVector("minimumIntegerDigits")),
- isolate->factory()->NewNumberFromInt(
- number_format->getMinimumIntegerDigits()),
+ factory->NewStringFromStaticAscii("minimumIntegerDigits"),
+ factory->NewNumberFromInt(number_format->getMinimumIntegerDigits()),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(
- CStrVector("minimumFractionDigits")),
- isolate->factory()->NewNumberFromInt(
- number_format->getMinimumFractionDigits()),
+ factory->NewStringFromStaticAscii("minimumFractionDigits"),
+ factory->NewNumberFromInt(number_format->getMinimumFractionDigits()),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(
- CStrVector("maximumFractionDigits")),
- isolate->factory()->NewNumberFromInt(
- number_format->getMaximumFractionDigits()),
+ factory->NewStringFromStaticAscii("maximumFractionDigits"),
+ factory->NewNumberFromInt(number_format->getMaximumFractionDigits()),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
- Handle<String> key = isolate->factory()->NewStringFromAscii(
- CStrVector("minimumSignificantDigits"));
+ Handle<String> key =
+ factory->NewStringFromStaticAscii("minimumSignificantDigits");
if (JSReceiver::HasLocalProperty(resolved, key)) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(
- CStrVector("minimumSignificantDigits")),
- isolate->factory()->NewNumberFromInt(
- number_format->getMinimumSignificantDigits()),
+ factory->NewStringFromStaticAscii("minimumSignificantDigits"),
+ factory->NewNumberFromInt(number_format->getMinimumSignificantDigits()),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
}
- key = isolate->factory()->NewStringFromAscii(
- CStrVector("maximumSignificantDigits"));
+ key = factory->NewStringFromStaticAscii("maximumSignificantDigits");
if (JSReceiver::HasLocalProperty(resolved, key)) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(
- CStrVector("maximumSignificantDigits")),
- isolate->factory()->NewNumberFromInt(
- number_format->getMaximumSignificantDigits()),
+ factory->NewStringFromStaticAscii("maximumSignificantDigits"),
+ factory->NewNumberFromInt(number_format->getMaximumSignificantDigits()),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
}
// Set the locale
@@ -497,18 +462,18 @@ void SetResolvedNumberSettings(Isolate* isolate,
if (U_SUCCESS(status)) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector(result)),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromAsciiChecked(result),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
} else {
// This would never happen, since we got the locale from ICU.
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector("und")),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromStaticAscii("und"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
}
}
@@ -581,135 +546,136 @@ void SetResolvedCollatorSettings(Isolate* isolate,
const icu::Locale& icu_locale,
icu::Collator* collator,
Handle<JSObject> resolved) {
+ Factory* factory = isolate->factory();
UErrorCode status = U_ZERO_ERROR;
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("numeric")),
- isolate->factory()->ToBoolean(
+ factory->NewStringFromStaticAscii("numeric"),
+ factory->ToBoolean(
collator->getAttribute(UCOL_NUMERIC_COLLATION, status) == UCOL_ON),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
switch (collator->getAttribute(UCOL_CASE_FIRST, status)) {
case UCOL_LOWER_FIRST:
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("caseFirst")),
- isolate->factory()->NewStringFromAscii(CStrVector("lower")),
+ factory->NewStringFromStaticAscii("caseFirst"),
+ factory->NewStringFromStaticAscii("lower"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
break;
case UCOL_UPPER_FIRST:
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("caseFirst")),
- isolate->factory()->NewStringFromAscii(CStrVector("upper")),
+ factory->NewStringFromStaticAscii("caseFirst"),
+ factory->NewStringFromStaticAscii("upper"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
break;
default:
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("caseFirst")),
- isolate->factory()->NewStringFromAscii(CStrVector("false")),
+ factory->NewStringFromStaticAscii("caseFirst"),
+ factory->NewStringFromStaticAscii("false"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
}
switch (collator->getAttribute(UCOL_STRENGTH, status)) {
case UCOL_PRIMARY: {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("strength")),
- isolate->factory()->NewStringFromAscii(CStrVector("primary")),
+ factory->NewStringFromStaticAscii("strength"),
+ factory->NewStringFromStaticAscii("primary"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
// case level: true + s1 -> case, s1 -> base.
if (UCOL_ON == collator->getAttribute(UCOL_CASE_LEVEL, status)) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
- isolate->factory()->NewStringFromAscii(CStrVector("case")),
+ factory->NewStringFromStaticAscii("sensitivity"),
+ factory->NewStringFromStaticAscii("case"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
} else {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
- isolate->factory()->NewStringFromAscii(CStrVector("base")),
+ factory->NewStringFromStaticAscii("sensitivity"),
+ factory->NewStringFromStaticAscii("base"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
}
break;
}
case UCOL_SECONDARY:
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("strength")),
- isolate->factory()->NewStringFromAscii(CStrVector("secondary")),
+ factory->NewStringFromStaticAscii("strength"),
+ factory->NewStringFromStaticAscii("secondary"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
- isolate->factory()->NewStringFromAscii(CStrVector("accent")),
+ factory->NewStringFromStaticAscii("sensitivity"),
+ factory->NewStringFromStaticAscii("accent"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
break;
case UCOL_TERTIARY:
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("strength")),
- isolate->factory()->NewStringFromAscii(CStrVector("tertiary")),
+ factory->NewStringFromStaticAscii("strength"),
+ factory->NewStringFromStaticAscii("tertiary"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
- isolate->factory()->NewStringFromAscii(CStrVector("variant")),
+ factory->NewStringFromStaticAscii("sensitivity"),
+ factory->NewStringFromStaticAscii("variant"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
break;
case UCOL_QUATERNARY:
// We shouldn't get quaternary and identical from ICU, but if we do
// put them into variant.
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("strength")),
- isolate->factory()->NewStringFromAscii(CStrVector("quaternary")),
+ factory->NewStringFromStaticAscii("strength"),
+ factory->NewStringFromStaticAscii("quaternary"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
- isolate->factory()->NewStringFromAscii(CStrVector("variant")),
+ factory->NewStringFromStaticAscii("sensitivity"),
+ factory->NewStringFromStaticAscii("variant"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
break;
default:
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("strength")),
- isolate->factory()->NewStringFromAscii(CStrVector("identical")),
+ factory->NewStringFromStaticAscii("strength"),
+ factory->NewStringFromStaticAscii("identical"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
- isolate->factory()->NewStringFromAscii(CStrVector("variant")),
+ factory->NewStringFromStaticAscii("sensitivity"),
+ factory->NewStringFromStaticAscii("variant"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
}
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("ignorePunctuation")),
- isolate->factory()->ToBoolean(collator->getAttribute(
+ factory->NewStringFromStaticAscii("ignorePunctuation"),
+ factory->ToBoolean(collator->getAttribute(
UCOL_ALTERNATE_HANDLING, status) == UCOL_SHIFTED),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
// Set the locale
char result[ULOC_FULLNAME_CAPACITY];
@@ -719,18 +685,18 @@ void SetResolvedCollatorSettings(Isolate* isolate,
if (U_SUCCESS(status)) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector(result)),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromAsciiChecked(result),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
} else {
// This would never happen, since we got the locale from ICU.
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector("und")),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromStaticAscii("und"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
}
}
@@ -772,6 +738,7 @@ void SetResolvedBreakIteratorSettings(Isolate* isolate,
const icu::Locale& icu_locale,
icu::BreakIterator* break_iterator,
Handle<JSObject> resolved) {
+ Factory* factory = isolate->factory();
UErrorCode status = U_ZERO_ERROR;
// Set the locale
@@ -782,18 +749,18 @@ void SetResolvedBreakIteratorSettings(Isolate* isolate,
if (U_SUCCESS(status)) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector(result)),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromAsciiChecked(result),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
} else {
// This would never happen, since we got the locale from ICU.
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector("und")),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromStaticAscii("und"),
NONE,
- SLOPPY);
+ SLOPPY).Assert();
}
}
@@ -855,7 +822,7 @@ icu::SimpleDateFormat* DateFormat::UnpackDateFormat(
Isolate* isolate,
Handle<JSObject> obj) {
Handle<String> key =
- isolate->factory()->NewStringFromAscii(CStrVector("dateFormat"));
+ isolate->factory()->NewStringFromStaticAscii("dateFormat");
if (JSReceiver::HasLocalProperty(obj, key)) {
return reinterpret_cast<icu::SimpleDateFormat*>(
obj->GetInternalField(0));
@@ -929,7 +896,7 @@ icu::DecimalFormat* NumberFormat::UnpackNumberFormat(
Isolate* isolate,
Handle<JSObject> obj) {
Handle<String> key =
- isolate->factory()->NewStringFromAscii(CStrVector("numberFormat"));
+ isolate->factory()->NewStringFromStaticAscii("numberFormat");
if (JSReceiver::HasLocalProperty(obj, key)) {
return reinterpret_cast<icu::DecimalFormat*>(obj->GetInternalField(0));
}
@@ -984,8 +951,7 @@ icu::Collator* Collator::InitializeCollator(
icu::Collator* Collator::UnpackCollator(Isolate* isolate,
Handle<JSObject> obj) {
- Handle<String> key =
- isolate->factory()->NewStringFromAscii(CStrVector("collator"));
+ Handle<String> key = isolate->factory()->NewStringFromStaticAscii("collator");
if (JSReceiver::HasLocalProperty(obj, key)) {
return reinterpret_cast<icu::Collator*>(obj->GetInternalField(0));
}
@@ -1044,7 +1010,7 @@ icu::BreakIterator* BreakIterator::InitializeBreakIterator(
icu::BreakIterator* BreakIterator::UnpackBreakIterator(Isolate* isolate,
Handle<JSObject> obj) {
Handle<String> key =
- isolate->factory()->NewStringFromAscii(CStrVector("breakIterator"));
+ isolate->factory()->NewStringFromStaticAscii("breakIterator");
if (JSReceiver::HasLocalProperty(obj, key)) {
return reinterpret_cast<icu::BreakIterator*>(obj->GetInternalField(0));
}
diff --git a/deps/v8/src/i18n.h b/deps/v8/src/i18n.h
index 50beb49ba1..e312322b6f 100644
--- a/deps/v8/src/i18n.h
+++ b/deps/v8/src/i18n.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// limitations under the License.
#ifndef V8_I18N_H_
diff --git a/deps/v8/src/i18n.js b/deps/v8/src/i18n.js
index 2e5485749a..4fcb02b440 100644
--- a/deps/v8/src/i18n.js
+++ b/deps/v8/src/i18n.js
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// limitations under the License.
// ECMAScript 402 API implementation.
@@ -232,8 +209,7 @@ var ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR =
*/
function addBoundMethod(obj, methodName, implementation, length) {
function getter() {
- if (!this || typeof this !== 'object' ||
- this.__initializedIntlObject === undefined) {
+ if (!%IsInitializedIntlObject(this)) {
throw new $TypeError('Method ' + methodName + ' called on a ' +
'non-object or on a wrong type of object.');
}
@@ -282,7 +258,7 @@ function addBoundMethod(obj, methodName, implementation, length) {
%FunctionRemovePrototype(getter);
%SetNativeFlag(getter);
- $Object.defineProperty(obj.prototype, methodName, {
+ ObjectDefineProperty(obj.prototype, methodName, {
get: getter,
enumerable: false,
configurable: true
@@ -303,7 +279,7 @@ function supportedLocalesOf(service, locales, options) {
if (options === undefined) {
options = {};
} else {
- options = toObject(options);
+ options = ToObject(options);
}
var matcher = options.localeMatcher;
@@ -537,18 +513,6 @@ function parseExtension(extension) {
/**
- * Converts parameter to an Object if possible.
- */
-function toObject(value) {
- if (IS_NULL_OR_UNDEFINED(value)) {
- throw new $TypeError('Value cannot be converted to an Object.');
- }
-
- return $Object(value);
-}
-
-
-/**
* Populates internalOptions object with boolean key-value pairs
* from extensionMap and options.
* Returns filtered extension (number and date format constructors use
@@ -617,15 +581,14 @@ function setOptions(inOptions, extensionMap, keyValues, getOption, outOptions) {
*/
function freezeArray(array) {
array.forEach(function(element, index) {
- $Object.defineProperty(array, index, {value: element,
+ ObjectDefineProperty(array, index, {value: element,
configurable: false,
writable: false,
enumerable: true});
});
- $Object.defineProperty(array, 'length', {value: array.length,
- writable: false});
-
+ ObjectDefineProperty(array, 'length', {value: array.length,
+ writable: false});
return array;
}
@@ -686,8 +649,8 @@ function getAvailableLocalesOf(service) {
* Configurable is false by default.
*/
function defineWEProperty(object, property, value) {
- $Object.defineProperty(object, property,
- {value: value, writable: true, enumerable: true});
+ ObjectDefineProperty(object, property,
+ {value: value, writable: true, enumerable: true});
}
@@ -706,11 +669,11 @@ function addWEPropertyIfDefined(object, property, value) {
* Defines a property and sets writable, enumerable and configurable to true.
*/
function defineWECProperty(object, property, value) {
- $Object.defineProperty(object, property,
- {value: value,
- writable: true,
- enumerable: true,
- configurable: true});
+ ObjectDefineProperty(object, property,
+ {value: value,
+ writable: true,
+ enumerable: true,
+ configurable: true});
}
@@ -777,7 +740,7 @@ function initializeLocaleList(locales) {
return freezeArray(seen);
}
- var o = toObject(locales);
+ var o = ToObject(locales);
// Converts it to UInt32 (>>> is shr on 32bit integers).
var len = o.length >>> 0;
@@ -896,7 +859,7 @@ function BuildLanguageTagREs() {
* Useful for subclassing.
*/
function initializeCollator(collator, locales, options) {
- if (collator.hasOwnProperty('__initializedIntlObject')) {
+ if (%IsInitializedIntlObject(collator)) {
throw new $TypeError('Trying to re-initialize Collator object.');
}
@@ -949,8 +912,8 @@ function initializeCollator(collator, locales, options) {
// We define all properties C++ code may produce, to prevent security
// problems. If malicious user decides to redefine Object.prototype.locale
// we can't just use plain x.locale = 'us' or in C++ Set("locale", "us").
- // Object.defineProperties will either succeed defining or throw an error.
- var resolved = $Object.defineProperties({}, {
+ // ObjectDefineProperties will either succeed defining or throw an error.
+ var resolved = ObjectDefineProperties({}, {
caseFirst: {writable: true},
collation: {value: internalOptions.collation, writable: true},
ignorePunctuation: {writable: true},
@@ -967,10 +930,8 @@ function initializeCollator(collator, locales, options) {
resolved);
// Writable, configurable and enumerable are set to false by default.
- $Object.defineProperty(collator, 'collator', {value: internalCollator});
- $Object.defineProperty(collator, '__initializedIntlObject',
- {value: 'collator'});
- $Object.defineProperty(collator, 'resolved', {value: resolved});
+ %MarkAsInitializedIntlObjectOfType(collator, 'collator', internalCollator);
+ ObjectDefineProperty(collator, 'resolved', {value: resolved});
return collator;
}
@@ -991,7 +952,7 @@ function initializeCollator(collator, locales, options) {
return new Intl.Collator(locales, options);
}
- return initializeCollator(toObject(this), locales, options);
+ return initializeCollator(ToObject(this), locales, options);
},
DONT_ENUM
);
@@ -1005,8 +966,7 @@ function initializeCollator(collator, locales, options) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
}
- if (!this || typeof this !== 'object' ||
- this.__initializedIntlObject !== 'collator') {
+ if (!%IsInitializedIntlObjectOfType(this, 'collator')) {
throw new $TypeError('resolvedOptions method called on a non-object ' +
'or on a object that is not Intl.Collator.');
}
@@ -1063,7 +1023,8 @@ function initializeCollator(collator, locales, options) {
* the sort order, or x comes after y in the sort order, respectively.
*/
function compare(collator, x, y) {
- return %InternalCompare(collator.collator, $String(x), $String(y));
+ return %InternalCompare(%GetImplFromInitializedIntlObject(collator),
+ $String(x), $String(y));
};
@@ -1104,7 +1065,7 @@ function getNumberOption(options, property, min, max, fallback) {
* Useful for subclassing.
*/
function initializeNumberFormat(numberFormat, locales, options) {
- if (numberFormat.hasOwnProperty('__initializedIntlObject')) {
+ if (%IsInitializedIntlObject(numberFormat)) {
throw new $TypeError('Trying to re-initialize NumberFormat object.');
}
@@ -1167,7 +1128,7 @@ function initializeNumberFormat(numberFormat, locales, options) {
getOption, internalOptions);
var requestedLocale = locale.locale + extension;
- var resolved = $Object.defineProperties({}, {
+ var resolved = ObjectDefineProperties({}, {
currency: {writable: true},
currencyDisplay: {writable: true},
locale: {writable: true},
@@ -1192,14 +1153,12 @@ function initializeNumberFormat(numberFormat, locales, options) {
// We can't get information about number or currency style from ICU, so we
// assume user request was fulfilled.
if (internalOptions.style === 'currency') {
- $Object.defineProperty(resolved, 'currencyDisplay', {value: currencyDisplay,
- writable: true});
+ ObjectDefineProperty(resolved, 'currencyDisplay', {value: currencyDisplay,
+ writable: true});
}
- $Object.defineProperty(numberFormat, 'formatter', {value: formatter});
- $Object.defineProperty(numberFormat, 'resolved', {value: resolved});
- $Object.defineProperty(numberFormat, '__initializedIntlObject',
- {value: 'numberformat'});
+ %MarkAsInitializedIntlObjectOfType(numberFormat, 'numberformat', formatter);
+ ObjectDefineProperty(numberFormat, 'resolved', {value: resolved});
return numberFormat;
}
@@ -1220,7 +1179,7 @@ function initializeNumberFormat(numberFormat, locales, options) {
return new Intl.NumberFormat(locales, options);
}
- return initializeNumberFormat(toObject(this), locales, options);
+ return initializeNumberFormat(ToObject(this), locales, options);
},
DONT_ENUM
);
@@ -1234,8 +1193,7 @@ function initializeNumberFormat(numberFormat, locales, options) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
}
- if (!this || typeof this !== 'object' ||
- this.__initializedIntlObject !== 'numberformat') {
+ if (!%IsInitializedIntlObjectOfType(this, 'numberformat')) {
throw new $TypeError('resolvedOptions method called on a non-object' +
' or on a object that is not Intl.NumberFormat.');
}
@@ -1309,7 +1267,8 @@ function formatNumber(formatter, value) {
// Spec treats -0 and +0 as 0.
var number = $Number(value) + 0;
- return %InternalNumberFormat(formatter.formatter, number);
+ return %InternalNumberFormat(%GetImplFromInitializedIntlObject(formatter),
+ number);
}
@@ -1317,7 +1276,8 @@ function formatNumber(formatter, value) {
* Returns a Number that represents string value that was passed in.
*/
function parseNumber(formatter, value) {
- return %InternalNumberParse(formatter.formatter, $String(value));
+ return %InternalNumberParse(%GetImplFromInitializedIntlObject(formatter),
+ $String(value));
}
@@ -1470,13 +1430,11 @@ function appendToDateTimeObject(options, option, match, pairs) {
*/
function toDateTimeOptions(options, required, defaults) {
if (options === undefined) {
- options = null;
+ options = {};
} else {
- options = toObject(options);
+ options = TO_OBJECT_INLINE(options);
}
- options = $Object.apply(this, [options]);
-
var needsDefault = true;
if ((required === 'date' || required === 'any') &&
(options.weekday !== undefined || options.year !== undefined ||
@@ -1491,30 +1449,30 @@ function toDateTimeOptions(options, required, defaults) {
}
if (needsDefault && (defaults === 'date' || defaults === 'all')) {
- $Object.defineProperty(options, 'year', {value: 'numeric',
- writable: true,
- enumerable: true,
- configurable: true});
- $Object.defineProperty(options, 'month', {value: 'numeric',
- writable: true,
- enumerable: true,
- configurable: true});
- $Object.defineProperty(options, 'day', {value: 'numeric',
+ ObjectDefineProperty(options, 'year', {value: 'numeric',
+ writable: true,
+ enumerable: true,
+ configurable: true});
+ ObjectDefineProperty(options, 'month', {value: 'numeric',
writable: true,
enumerable: true,
configurable: true});
+ ObjectDefineProperty(options, 'day', {value: 'numeric',
+ writable: true,
+ enumerable: true,
+ configurable: true});
}
if (needsDefault && (defaults === 'time' || defaults === 'all')) {
- $Object.defineProperty(options, 'hour', {value: 'numeric',
+ ObjectDefineProperty(options, 'hour', {value: 'numeric',
writable: true,
enumerable: true,
configurable: true});
- $Object.defineProperty(options, 'minute', {value: 'numeric',
+ ObjectDefineProperty(options, 'minute', {value: 'numeric',
writable: true,
enumerable: true,
configurable: true});
- $Object.defineProperty(options, 'second', {value: 'numeric',
+ ObjectDefineProperty(options, 'second', {value: 'numeric',
writable: true,
enumerable: true,
configurable: true});
@@ -1530,7 +1488,7 @@ function toDateTimeOptions(options, required, defaults) {
*/
function initializeDateTimeFormat(dateFormat, locales, options) {
- if (dateFormat.hasOwnProperty('__initializedIntlObject')) {
+ if (%IsInitializedIntlObject(dateFormat)) {
throw new $TypeError('Trying to re-initialize DateTimeFormat object.');
}
@@ -1565,7 +1523,7 @@ function initializeDateTimeFormat(dateFormat, locales, options) {
getOption, internalOptions);
var requestedLocale = locale.locale + extension;
- var resolved = $Object.defineProperties({}, {
+ var resolved = ObjectDefineProperties({}, {
calendar: {writable: true},
day: {writable: true},
era: {writable: true},
@@ -1592,10 +1550,8 @@ function initializeDateTimeFormat(dateFormat, locales, options) {
throw new $RangeError('Unsupported time zone specified ' + tz);
}
- $Object.defineProperty(dateFormat, 'formatter', {value: formatter});
- $Object.defineProperty(dateFormat, 'resolved', {value: resolved});
- $Object.defineProperty(dateFormat, '__initializedIntlObject',
- {value: 'dateformat'});
+ %MarkAsInitializedIntlObjectOfType(dateFormat, 'dateformat', formatter);
+ ObjectDefineProperty(dateFormat, 'resolved', {value: resolved});
return dateFormat;
}
@@ -1616,7 +1572,7 @@ function initializeDateTimeFormat(dateFormat, locales, options) {
return new Intl.DateTimeFormat(locales, options);
}
- return initializeDateTimeFormat(toObject(this), locales, options);
+ return initializeDateTimeFormat(ToObject(this), locales, options);
},
DONT_ENUM
);
@@ -1630,8 +1586,7 @@ function initializeDateTimeFormat(dateFormat, locales, options) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
}
- if (!this || typeof this !== 'object' ||
- this.__initializedIntlObject !== 'dateformat') {
+ if (!%IsInitializedIntlObjectOfType(this, 'dateformat')) {
throw new $TypeError('resolvedOptions method called on a non-object or ' +
'on a object that is not Intl.DateTimeFormat.');
}
@@ -1713,7 +1668,8 @@ function formatDate(formatter, dateValue) {
throw new $RangeError('Provided date is not in valid range.');
}
- return %InternalDateFormat(formatter.formatter, new $Date(dateMs));
+ return %InternalDateFormat(%GetImplFromInitializedIntlObject(formatter),
+ new $Date(dateMs));
}
@@ -1724,7 +1680,8 @@ function formatDate(formatter, dateValue) {
* Returns undefined if date string cannot be parsed.
*/
function parseDate(formatter, value) {
- return %InternalDateParse(formatter.formatter, $String(value));
+ return %InternalDateParse(%GetImplFromInitializedIntlObject(formatter),
+ $String(value));
}
@@ -1772,7 +1729,7 @@ function canonicalizeTimeZoneID(tzID) {
* Useful for subclassing.
*/
function initializeBreakIterator(iterator, locales, options) {
- if (iterator.hasOwnProperty('__initializedIntlObject')) {
+ if (%IsInitializedIntlObject(iterator)) {
throw new $TypeError('Trying to re-initialize v8BreakIterator object.');
}
@@ -1788,7 +1745,7 @@ function initializeBreakIterator(iterator, locales, options) {
'type', 'string', ['character', 'word', 'sentence', 'line'], 'word'));
var locale = resolveLocale('breakiterator', locales, options);
- var resolved = $Object.defineProperties({}, {
+ var resolved = ObjectDefineProperties({}, {
requestedLocale: {value: locale.locale, writable: true},
type: {value: internalOptions.type, writable: true},
locale: {writable: true}
@@ -1798,10 +1755,9 @@ function initializeBreakIterator(iterator, locales, options) {
internalOptions,
resolved);
- $Object.defineProperty(iterator, 'iterator', {value: internalIterator});
- $Object.defineProperty(iterator, 'resolved', {value: resolved});
- $Object.defineProperty(iterator, '__initializedIntlObject',
- {value: 'breakiterator'});
+ %MarkAsInitializedIntlObjectOfType(iterator, 'breakiterator',
+ internalIterator);
+ ObjectDefineProperty(iterator, 'resolved', {value: resolved});
return iterator;
}
@@ -1822,7 +1778,7 @@ function initializeBreakIterator(iterator, locales, options) {
return new Intl.v8BreakIterator(locales, options);
}
- return initializeBreakIterator(toObject(this), locales, options);
+ return initializeBreakIterator(ToObject(this), locales, options);
},
DONT_ENUM
);
@@ -1836,8 +1792,7 @@ function initializeBreakIterator(iterator, locales, options) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
}
- if (!this || typeof this !== 'object' ||
- this.__initializedIntlObject !== 'breakiterator') {
+ if (!%IsInitializedIntlObjectOfType(this, 'breakiterator')) {
throw new $TypeError('resolvedOptions method called on a non-object or ' +
'on a object that is not Intl.v8BreakIterator.');
}
@@ -1884,7 +1839,8 @@ function initializeBreakIterator(iterator, locales, options) {
* gets discarded.
*/
function adoptText(iterator, text) {
- %BreakIteratorAdoptText(iterator.iterator, $String(text));
+ %BreakIteratorAdoptText(%GetImplFromInitializedIntlObject(iterator),
+ $String(text));
}
@@ -1892,7 +1848,7 @@ function adoptText(iterator, text) {
* Returns index of the first break in the string and moves current pointer.
*/
function first(iterator) {
- return %BreakIteratorFirst(iterator.iterator);
+ return %BreakIteratorFirst(%GetImplFromInitializedIntlObject(iterator));
}
@@ -1900,7 +1856,7 @@ function first(iterator) {
* Returns the index of the next break and moves the pointer.
*/
function next(iterator) {
- return %BreakIteratorNext(iterator.iterator);
+ return %BreakIteratorNext(%GetImplFromInitializedIntlObject(iterator));
}
@@ -1908,7 +1864,7 @@ function next(iterator) {
* Returns index of the current break.
*/
function current(iterator) {
- return %BreakIteratorCurrent(iterator.iterator);
+ return %BreakIteratorCurrent(%GetImplFromInitializedIntlObject(iterator));
}
@@ -1916,7 +1872,7 @@ function current(iterator) {
* Returns type of the current break.
*/
function breakType(iterator) {
- return %BreakIteratorBreakType(iterator.iterator);
+ return %BreakIteratorBreakType(%GetImplFromInitializedIntlObject(iterator));
}
@@ -1967,7 +1923,7 @@ function cachedOrNewService(service, locales, options, defaults) {
* Compares this and that, and returns less than 0, 0 or greater than 0 value.
* Overrides the built-in method.
*/
-$Object.defineProperty($String.prototype, 'localeCompare', {
+ObjectDefineProperty($String.prototype, 'localeCompare', {
value: function(that) {
if (%_IsConstructCall()) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
@@ -1998,7 +1954,7 @@ $Object.defineProperty($String.prototype, 'localeCompare', {
* If the form is not one of "NFC", "NFD", "NFKC", or "NFKD", then throw
* a RangeError Exception.
*/
-$Object.defineProperty($String.prototype, 'normalize', {
+ObjectDefineProperty($String.prototype, 'normalize', {
value: function(that) {
if (%_IsConstructCall()) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
@@ -2029,7 +1985,7 @@ $Object.defineProperty($String.prototype, 'normalize', {
* Formats a Number object (this) using locale and options values.
* If locale or options are omitted, defaults are used.
*/
-$Object.defineProperty($Number.prototype, 'toLocaleString', {
+ObjectDefineProperty($Number.prototype, 'toLocaleString', {
value: function() {
if (%_IsConstructCall()) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
@@ -2079,7 +2035,7 @@ function toLocaleDateTime(date, locales, options, required, defaults, service) {
* If locale or options are omitted, defaults are used - both date and time are
* present in the output.
*/
-$Object.defineProperty($Date.prototype, 'toLocaleString', {
+ObjectDefineProperty($Date.prototype, 'toLocaleString', {
value: function() {
if (%_IsConstructCall()) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
@@ -2104,7 +2060,7 @@ $Object.defineProperty($Date.prototype, 'toLocaleString', {
* If locale or options are omitted, defaults are used - only date is present
* in the output.
*/
-$Object.defineProperty($Date.prototype, 'toLocaleDateString', {
+ObjectDefineProperty($Date.prototype, 'toLocaleDateString', {
value: function() {
if (%_IsConstructCall()) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
@@ -2129,7 +2085,7 @@ $Object.defineProperty($Date.prototype, 'toLocaleDateString', {
* If locale or options are omitted, defaults are used - only time is present
* in the output.
*/
-$Object.defineProperty($Date.prototype, 'toLocaleTimeString', {
+ObjectDefineProperty($Date.prototype, 'toLocaleTimeString', {
value: function() {
if (%_IsConstructCall()) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
diff --git a/deps/v8/src/ia32/assembler-ia32-inl.h b/deps/v8/src/ia32/assembler-ia32-inl.h
index 8022f0592b..97aeeae72c 100644
--- a/deps/v8/src/ia32/assembler-ia32-inl.h
+++ b/deps/v8/src/ia32/assembler-ia32-inl.h
@@ -285,14 +285,12 @@ void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
CPU::FlushICache(pc_, sizeof(Address));
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
visitor->VisitCodeAgeSequence(this);
- #ifdef ENABLE_DEBUGGER_SUPPORT
} else if (((RelocInfo::IsJSReturn(mode) &&
IsPatchedReturnSequence()) ||
(RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence())) &&
isolate->debug()->has_break_points()) {
visitor->VisitDebugTarget(this);
-#endif
} else if (IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this);
}
@@ -314,14 +312,12 @@ void RelocInfo::Visit(Heap* heap) {
CPU::FlushICache(pc_, sizeof(Address));
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
StaticVisitor::VisitCodeAgeSequence(heap, this);
-#ifdef ENABLE_DEBUGGER_SUPPORT
} else if (heap->isolate()->debug()->has_break_points() &&
((RelocInfo::IsJSReturn(mode) &&
IsPatchedReturnSequence()) ||
(RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence()))) {
StaticVisitor::VisitDebugTarget(heap, this);
-#endif
} else if (IsRuntimeEntry(mode)) {
StaticVisitor::VisitRuntimeEntry(this);
}
diff --git a/deps/v8/src/ia32/assembler-ia32.cc b/deps/v8/src/ia32/assembler-ia32.cc
index 3a4f590c8f..7a88e70827 100644
--- a/deps/v8/src/ia32/assembler-ia32.cc
+++ b/deps/v8/src/ia32/assembler-ia32.cc
@@ -89,13 +89,13 @@ const char* IntelDoubleRegister::AllocationIndexToString(int index) {
}
-void CpuFeatures::Probe() {
+void CpuFeatures::Probe(bool serializer_enabled) {
ASSERT(!initialized_);
ASSERT(supported_ == 0);
#ifdef DEBUG
initialized_ = true;
#endif
- if (Serializer::enabled()) {
+ if (serializer_enabled) {
supported_ |= OS::CpuFeaturesImpliedByPlatform();
return; // No features if we might serialize.
}
@@ -2703,12 +2703,7 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
ASSERT(!RelocInfo::IsNone(rmode));
// Don't record external references unless the heap will be serialized.
if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
-#ifdef DEBUG
- if (!Serializer::enabled()) {
- Serializer::TooLateToEnableNow();
- }
-#endif
- if (!Serializer::enabled() && !emit_debug_code()) {
+ if (!Serializer::enabled(isolate()) && !emit_debug_code()) {
return;
}
}
@@ -2717,16 +2712,17 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
}
-MaybeObject* Assembler::AllocateConstantPool(Heap* heap) {
+Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
// No out-of-line constant pool support.
- UNREACHABLE();
- return NULL;
+ ASSERT(!FLAG_enable_ool_constant_pool);
+ return isolate->factory()->empty_constant_pool_array();
}
void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
// No out-of-line constant pool support.
- UNREACHABLE();
+ ASSERT(!FLAG_enable_ool_constant_pool);
+ return;
}
diff --git a/deps/v8/src/ia32/assembler-ia32.h b/deps/v8/src/ia32/assembler-ia32.h
index 27e5302db3..3033db936b 100644
--- a/deps/v8/src/ia32/assembler-ia32.h
+++ b/deps/v8/src/ia32/assembler-ia32.h
@@ -530,7 +530,7 @@ class CpuFeatures : public AllStatic {
public:
// Detect features of the target CPU. Set safe defaults if the serializer
// is enabled (snapshots must be portable).
- static void Probe();
+ static void Probe(bool serializer_enabled);
// Check whether a feature is supported by the target CPU.
static bool IsSupported(CpuFeature f) {
@@ -543,15 +543,11 @@ class CpuFeatures : public AllStatic {
return Check(f, supported_);
}
- static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
- ASSERT(initialized_);
- return Check(f, found_by_runtime_probing_only_);
- }
-
- static bool IsSafeForSnapshot(CpuFeature f) {
+ static bool IsSafeForSnapshot(Isolate* isolate, CpuFeature f) {
return Check(f, cross_compile_) ||
(IsSupported(f) &&
- (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
+ !(Serializer::enabled(isolate) &&
+ Check(f, found_by_runtime_probing_only_)));
}
static bool VerifyCrossCompiling() {
@@ -564,6 +560,8 @@ class CpuFeatures : public AllStatic {
(cross_compile_ & mask) == mask;
}
+ static bool SupportsCrankshaft() { return IsSupported(SSE2); }
+
private:
static bool Check(CpuFeature f, uint64_t set) {
return (set & flag2set(f)) != 0;
@@ -1192,7 +1190,7 @@ class Assembler : public AssemblerBase {
void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
// Allocate a constant pool of the correct size for the generated code.
- MaybeObject* AllocateConstantPool(Heap* heap);
+ Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate);
// Generate the constant pool for the generated code.
void PopulateConstantPool(ConstantPoolArray* constant_pool);
diff --git a/deps/v8/src/ia32/builtins-ia32.cc b/deps/v8/src/ia32/builtins-ia32.cc
index 785c5fd61c..b3af2b2fed 100644
--- a/deps/v8/src/ia32/builtins-ia32.cc
+++ b/deps/v8/src/ia32/builtins-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -163,12 +140,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
Label rt_call, allocated;
if (FLAG_inline_new) {
Label undo_allocation;
-#ifdef ENABLE_DEBUGGER_SUPPORT
ExternalReference debug_step_in_fp =
ExternalReference::debug_step_in_fp_address(masm->isolate());
__ cmp(Operand::StaticVariable(debug_step_in_fp), Immediate(0));
__ j(not_equal, &rt_call);
-#endif
// Verified that the constructor is a JSFunction.
// Load the initial map and verify that it is in fact a map.
@@ -540,7 +515,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
if (is_construct) {
// No type feedback cell is available
__ mov(ebx, masm->isolate()->factory()->undefined_value());
- CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
+ CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
ParameterCount actual(eax);
@@ -702,8 +677,8 @@ void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) {
- if (Serializer::enabled()) {
- PlatformFeatureScope sse2(SSE2);
+ if (Serializer::enabled(masm->isolate())) {
+ PlatformFeatureScope sse2(masm->isolate(), SSE2);
Generate_NotifyStubFailureHelper(masm, kSaveFPRegs);
} else {
Generate_NotifyStubFailureHelper(masm, kSaveFPRegs);
@@ -949,7 +924,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// Out of stack space.
__ push(Operand(ebp, 4 * kPointerSize)); // push this
__ push(eax);
- __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
+ __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
__ bind(&okay);
// End of stack check.
@@ -1252,6 +1227,33 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
}
+static void ArgumentsAdaptorStackCheck(MacroAssembler* masm,
+ Label* stack_overflow) {
+ // ----------- S t a t e -------------
+ // -- eax : actual number of arguments
+ // -- ebx : expected number of arguments
+ // -- edi : function (passed through to callee)
+ // -----------------------------------
+ // Check the stack for overflow. We are not trying to catch
+ // interruptions (e.g. debug break and preemption) here, so the "real stack
+ // limit" is checked.
+ ExternalReference real_stack_limit =
+ ExternalReference::address_of_real_stack_limit(masm->isolate());
+ __ mov(edx, Operand::StaticVariable(real_stack_limit));
+ // Make ecx the space we have left. The stack might already be overflowed
+ // here which will cause ecx to become negative.
+ __ mov(ecx, esp);
+ __ sub(ecx, edx);
+ // Make edx the space we need for the array when it is unrolled onto the
+ // stack.
+ __ mov(edx, ebx);
+ __ shl(edx, kPointerSizeLog2);
+ // Check if the arguments will overflow the stack.
+ __ cmp(ecx, edx);
+ __ j(less_equal, stack_overflow); // Signed comparison.
+}
+
+
static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
__ push(ebp);
__ mov(ebp, esp);
@@ -1296,6 +1298,9 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
Label invoke, dont_adapt_arguments;
__ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1);
+ Label stack_overflow;
+ ArgumentsAdaptorStackCheck(masm, &stack_overflow);
+
Label enough, too_few;
__ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset));
__ cmp(eax, ebx);
@@ -1370,6 +1375,14 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// -------------------------------------------
__ bind(&dont_adapt_arguments);
__ jmp(edx);
+
+ __ bind(&stack_overflow);
+ {
+ FrameScope frame(masm, StackFrame::MANUAL);
+ EnterArgumentsAdaptorFrame(masm);
+ __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
+ __ int3();
+ }
}
diff --git a/deps/v8/src/ia32/code-stubs-ia32.cc b/deps/v8/src/ia32/code-stubs-ia32.cc
index ab29167e9a..174ebbbfaf 100644
--- a/deps/v8/src/ia32/code-stubs-ia32.cc
+++ b/deps/v8/src/ia32/code-stubs-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -44,7 +21,6 @@ namespace internal {
void FastNewClosureStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { ebx };
descriptor->register_param_count_ = 1;
@@ -55,7 +31,6 @@ void FastNewClosureStub::InitializeInterfaceDescriptor(
void FastNewContextStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edi };
descriptor->register_param_count_ = 1;
@@ -65,7 +40,6 @@ void FastNewContextStub::InitializeInterfaceDescriptor(
void ToNumberStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax };
descriptor->register_param_count_ = 1;
@@ -75,7 +49,6 @@ void ToNumberStub::InitializeInterfaceDescriptor(
void NumberToStringStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax };
descriptor->register_param_count_ = 1;
@@ -86,7 +59,6 @@ void NumberToStringStub::InitializeInterfaceDescriptor(
void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax, ebx, ecx };
descriptor->register_param_count_ = 3;
@@ -98,7 +70,6 @@ void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax, ebx, ecx, edx };
descriptor->register_param_count_ = 4;
@@ -109,7 +80,6 @@ void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { ebx, edx };
descriptor->register_param_count_ = 2;
@@ -119,7 +89,6 @@ void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, ecx };
descriptor->register_param_count_ = 2;
@@ -130,7 +99,6 @@ void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, ecx };
descriptor->register_param_count_ = 2;
@@ -141,7 +109,6 @@ void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
void RegExpConstructResultStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { ecx, ebx, eax };
descriptor->register_param_count_ = 3;
@@ -152,7 +119,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor(
void LoadFieldStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx };
descriptor->register_param_count_ = 1;
@@ -162,7 +128,6 @@ void LoadFieldStub::InitializeInterfaceDescriptor(
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx };
descriptor->register_param_count_ = 1;
@@ -172,7 +137,6 @@ void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
void StringLengthStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, ecx };
descriptor->register_param_count_ = 2;
@@ -182,7 +146,6 @@ void StringLengthStub::InitializeInterfaceDescriptor(
void KeyedStringLengthStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, ecx };
descriptor->register_param_count_ = 2;
@@ -192,7 +155,6 @@ void KeyedStringLengthStub::InitializeInterfaceDescriptor(
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, ecx, eax };
descriptor->register_param_count_ = 3;
@@ -203,7 +165,6 @@ void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
void TransitionElementsKindStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax, ebx };
descriptor->register_param_count_ = 2;
@@ -243,7 +204,6 @@ static void InitializeArrayConstructorDescriptor(
static void InitializeInternalArrayConstructorDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor,
int constant_stack_parameter_count) {
// register state
@@ -271,49 +231,42 @@ static void InitializeInternalArrayConstructorDescriptor(
void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(isolate, descriptor, 0);
+ InitializeArrayConstructorDescriptor(isolate(), descriptor, 0);
}
void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(isolate, descriptor, 1);
+ InitializeArrayConstructorDescriptor(isolate(), descriptor, 1);
}
void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(isolate, descriptor, -1);
+ InitializeArrayConstructorDescriptor(isolate(), descriptor, -1);
}
void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 0);
+ InitializeInternalArrayConstructorDescriptor(descriptor, 0);
}
void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 1);
+ InitializeInternalArrayConstructorDescriptor(descriptor, 1);
}
void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(isolate, descriptor, -1);
+ InitializeInternalArrayConstructorDescriptor(descriptor, -1);
}
void CompareNilICStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax };
descriptor->register_param_count_ = 1;
@@ -321,11 +274,10 @@ void CompareNilICStub::InitializeInterfaceDescriptor(
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(CompareNilIC_Miss);
descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate));
+ ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate()));
}
void ToBooleanStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax };
descriptor->register_param_count_ = 1;
@@ -333,12 +285,11 @@ void ToBooleanStub::InitializeInterfaceDescriptor(
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(ToBooleanIC_Miss);
descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate));
+ ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate()));
}
void StoreGlobalStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, ecx, eax };
descriptor->register_param_count_ = 3;
@@ -349,7 +300,6 @@ void StoreGlobalStub::InitializeInterfaceDescriptor(
void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { eax, ebx, ecx, edx };
descriptor->register_param_count_ = 4;
@@ -360,19 +310,17 @@ void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
void BinaryOpICStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, eax };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate));
+ ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate()));
}
void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { ecx, edx, eax };
descriptor->register_param_count_ = 3;
@@ -383,7 +331,6 @@ void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
void StringAddStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { edx, eax };
descriptor->register_param_count_ = 2;
@@ -482,10 +429,9 @@ void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
// Update the static counter each time a new code stub is generated.
- Isolate* isolate = masm->isolate();
- isolate->counters()->code_stubs()->Increment();
+ isolate()->counters()->code_stubs()->Increment();
- CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate);
+ CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor();
int param_count = descriptor->register_param_count_;
{
// Call the runtime system in a fresh internal frame.
@@ -522,9 +468,9 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
AllowExternalCallThatCantCauseGC scope(masm);
__ PrepareCallCFunction(argument_count, ecx);
__ mov(Operand(esp, 0 * kPointerSize),
- Immediate(ExternalReference::isolate_address(masm->isolate())));
+ Immediate(ExternalReference::isolate_address(isolate())));
__ CallCFunction(
- ExternalReference::store_buffer_overflow_function(masm->isolate()),
+ ExternalReference::store_buffer_overflow_function(isolate()),
argument_count);
if (save_doubles_ == kSaveFPRegs) {
CpuFeatureScope scope(masm, SSE2);
@@ -781,7 +727,7 @@ void FloatingPointHelper::CheckFloatOperands(MacroAssembler* masm,
void MathPowStub::Generate(MacroAssembler* masm) {
CpuFeatureScope use_sse2(masm, SSE2);
- Factory* factory = masm->isolate()->factory();
+ Factory* factory = isolate()->factory();
const Register exponent = eax;
const Register base = edx;
const Register scratch = ecx;
@@ -1010,11 +956,11 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ Cvtsi2sd(double_exponent, exponent);
// Returning or bailing out.
- Counters* counters = masm->isolate()->counters();
+ Counters* counters = isolate()->counters();
if (exponent_type_ == ON_STACK) {
// The arguments are still on the stack.
__ bind(&call_runtime);
- __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
+ __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1);
// The stub is called from non-optimized code, which expects the result
// as heap number in exponent.
@@ -1031,7 +977,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ movsd(Operand(esp, 0 * kDoubleSize), double_base);
__ movsd(Operand(esp, 1 * kDoubleSize), double_exponent);
__ CallCFunction(
- ExternalReference::power_double_double_function(masm->isolate()), 4);
+ ExternalReference::power_double_double_function(isolate()), 4);
}
// Return value is in st(0) on ia32.
// Store it into the (fixed) result register.
@@ -1056,7 +1002,7 @@ void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
Label miss;
if (kind() == Code::KEYED_LOAD_IC) {
- __ cmp(ecx, Immediate(masm->isolate()->factory()->prototype_string()));
+ __ cmp(ecx, Immediate(isolate()->factory()->prototype_string()));
__ j(not_equal, &miss);
}
@@ -1152,8 +1098,6 @@ void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
- Isolate* isolate = masm->isolate();
-
// esp[0] : return address
// esp[4] : number of parameters (tagged)
// esp[8] : receiver displacement
@@ -1285,7 +1229,7 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
__ j(zero, &skip_parameter_map);
__ mov(FieldOperand(edi, FixedArray::kMapOffset),
- Immediate(isolate->factory()->sloppy_arguments_elements_map()));
+ Immediate(isolate()->factory()->sloppy_arguments_elements_map()));
__ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2))));
__ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax);
__ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi);
@@ -1306,7 +1250,7 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
__ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
__ add(ebx, Operand(esp, 4 * kPointerSize));
__ sub(ebx, eax);
- __ mov(ecx, isolate->factory()->the_hole_value());
+ __ mov(ecx, isolate()->factory()->the_hole_value());
__ mov(edx, edi);
__ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize));
// eax = loop variable (tagged)
@@ -1341,7 +1285,7 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
// esp[16] = address of receiver argument
// Copy arguments header and remaining slots (if there are any).
__ mov(FieldOperand(edi, FixedArray::kMapOffset),
- Immediate(isolate->factory()->fixed_array_map()));
+ Immediate(isolate()->factory()->fixed_array_map()));
__ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
Label arguments_loop, arguments_test;
@@ -1377,8 +1321,6 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
- Isolate* isolate = masm->isolate();
-
// esp[0] : return address
// esp[4] : number of parameters
// esp[8] : receiver displacement
@@ -1449,7 +1391,7 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
__ lea(edi, Operand(eax, Heap::kStrictArgumentsObjectSize));
__ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
__ mov(FieldOperand(edi, FixedArray::kMapOffset),
- Immediate(isolate->factory()->fixed_array_map()));
+ Immediate(isolate()->factory()->fixed_array_map()));
__ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
// Untag the length for the loop below.
@@ -1496,14 +1438,13 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
static const int kJSRegExpOffset = 4 * kPointerSize;
Label runtime;
- Factory* factory = masm->isolate()->factory();
+ Factory* factory = isolate()->factory();
// Ensure that a RegExp stack is allocated.
ExternalReference address_of_regexp_stack_memory_address =
- ExternalReference::address_of_regexp_stack_memory_address(
- masm->isolate());
+ ExternalReference::address_of_regexp_stack_memory_address(isolate());
ExternalReference address_of_regexp_stack_memory_size =
- ExternalReference::address_of_regexp_stack_memory_size(masm->isolate());
+ ExternalReference::address_of_regexp_stack_memory_size(isolate());
__ mov(ebx, Operand::StaticVariable(address_of_regexp_stack_memory_size));
__ test(ebx, ebx);
__ j(zero, &runtime);
@@ -1652,7 +1593,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// edx: code
// ecx: encoding of subject string (1 if ASCII, 0 if two_byte);
// All checks done. Now push arguments for native regexp code.
- Counters* counters = masm->isolate()->counters();
+ Counters* counters = isolate()->counters();
__ IncrementCounter(counters->regexp_entry_native(), 1);
// Isolates: note we add an additional parameter here (isolate pointer).
@@ -1661,7 +1602,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Argument 9: Pass current isolate address.
__ mov(Operand(esp, 8 * kPointerSize),
- Immediate(ExternalReference::isolate_address(masm->isolate())));
+ Immediate(ExternalReference::isolate_address(isolate())));
// Argument 8: Indicate that this is a direct call from JavaScript.
__ mov(Operand(esp, 7 * kPointerSize), Immediate(1));
@@ -1678,7 +1619,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Argument 5: static offsets vector buffer.
__ mov(Operand(esp, 4 * kPointerSize),
Immediate(ExternalReference::address_of_static_offsets_vector(
- masm->isolate())));
+ isolate())));
// Argument 2: Previous index.
__ SmiUntag(ebx);
@@ -1752,8 +1693,8 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// haven't created the exception yet. Handle that in the runtime system.
// TODO(592): Rerunning the RegExp to get the stack overflow exception.
ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
- masm->isolate());
- __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value()));
+ isolate());
+ __ mov(edx, Immediate(isolate()->factory()->the_hole_value()));
__ mov(eax, Operand::StaticVariable(pending_exception));
__ cmp(edx, eax);
__ j(equal, &runtime);
@@ -1834,7 +1775,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Get the static offsets vector filled by the native regexp code.
ExternalReference address_of_static_offsets_vector =
- ExternalReference::address_of_static_offsets_vector(masm->isolate());
+ ExternalReference::address_of_static_offsets_vector(isolate());
__ mov(ecx, Immediate(address_of_static_offsets_vector));
// ebx: last_match_info backing store (FixedArray)
@@ -2000,7 +1941,7 @@ void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
// Check for undefined. undefined OP undefined is false even though
// undefined == undefined.
Label check_for_nan;
- __ cmp(edx, masm->isolate()->factory()->undefined_value());
+ __ cmp(edx, isolate()->factory()->undefined_value());
__ j(not_equal, &check_for_nan, Label::kNear);
__ Move(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
__ ret(0);
@@ -2010,7 +1951,7 @@ void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
// Test for NaN. Compare heap numbers in a general way,
// to hanlde NaNs correctly.
__ cmp(FieldOperand(edx, HeapObject::kMapOffset),
- Immediate(masm->isolate()->factory()->heap_number_map()));
+ Immediate(isolate()->factory()->heap_number_map()));
__ j(equal, &generic_heap_number_comparison, Label::kNear);
if (cc != equal) {
// Call runtime on identical JSObjects. Otherwise return equal.
@@ -2055,7 +1996,7 @@ void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
// Check if the non-smi operand is a heap number.
__ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
- Immediate(masm->isolate()->factory()->heap_number_map()));
+ Immediate(isolate()->factory()->heap_number_map()));
// If heap number, handle it in the slow case.
__ j(equal, &slow, Label::kNear);
// Return non-equal (ebx is not zero)
@@ -2284,8 +2225,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// If we didn't have a matching function, and we didn't find the megamorph
// sentinel, then we have in the slot either some other function or an
// AllocationSite. Do a map check on the object in ecx.
- Handle<Map> allocation_site_map =
- masm->isolate()->factory()->allocation_site_map();
+ Handle<Map> allocation_site_map = isolate->factory()->allocation_site_map();
__ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map));
__ j(not_equal, &miss);
@@ -2332,7 +2272,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
__ push(edx);
__ push(ebx);
- CreateAllocationSiteStub create_stub;
+ CreateAllocationSiteStub create_stub(isolate);
__ CallStub(&create_stub);
__ pop(ebx);
@@ -2363,12 +2303,65 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
}
+static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
+ // Do not transform the receiver for strict mode functions.
+ __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
+ __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset),
+ 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
+ __ j(not_equal, cont);
+
+ // Do not transform the receiver for natives (shared already in ecx).
+ __ test_b(FieldOperand(ecx, SharedFunctionInfo::kNativeByteOffset),
+ 1 << SharedFunctionInfo::kNativeBitWithinByte);
+ __ j(not_equal, cont);
+}
+
+
+static void EmitSlowCase(Isolate* isolate,
+ MacroAssembler* masm,
+ int argc,
+ Label* non_function) {
+ // Check for function proxy.
+ __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE);
+ __ j(not_equal, non_function);
+ __ pop(ecx);
+ __ push(edi); // put proxy as additional argument under return address
+ __ push(ecx);
+ __ Move(eax, Immediate(argc + 1));
+ __ Move(ebx, Immediate(0));
+ __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
+ {
+ Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline();
+ __ jmp(adaptor, RelocInfo::CODE_TARGET);
+ }
+
+ // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
+ // of the original receiver from the call site).
+ __ bind(non_function);
+ __ mov(Operand(esp, (argc + 1) * kPointerSize), edi);
+ __ Move(eax, Immediate(argc));
+ __ Move(ebx, Immediate(0));
+ __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
+ Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline();
+ __ jmp(adaptor, RelocInfo::CODE_TARGET);
+}
+
+
+static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) {
+ // Wrap the receiver and patch it back onto the stack.
+ { FrameScope frame_scope(masm, StackFrame::INTERNAL);
+ __ push(edi);
+ __ push(eax);
+ __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
+ __ pop(edi);
+ }
+ __ mov(Operand(esp, (argc + 1) * kPointerSize), eax);
+ __ jmp(cont);
+}
+
+
void CallFunctionStub::Generate(MacroAssembler* masm) {
- // ebx : feedback vector
- // edx : (only if ebx is not the megamorphic symbol) slot in feedback
- // vector (Smi)
// edi : the function to call
- Isolate* isolate = masm->isolate();
Label slow, non_function, wrap, cont;
if (NeedsChecks()) {
@@ -2378,14 +2371,6 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// Goto slow case if we do not have a function.
__ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
__ j(not_equal, &slow);
-
- if (RecordCallTarget()) {
- GenerateRecordCallTarget(masm);
- // Type information was updated. Because we may call Array, which
- // expects either undefined or an AllocationSite in ebx we need
- // to set ebx to undefined.
- __ mov(ebx, Immediate(isolate->factory()->undefined_value()));
- }
}
// Fast-case: Just invoke the function.
@@ -2393,16 +2378,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
if (CallAsMethod()) {
if (NeedsChecks()) {
- // Do not transform the receiver for strict mode functions.
- __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
- __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset),
- 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
- __ j(not_equal, &cont);
-
- // Do not transform the receiver for natives (shared already in ecx).
- __ test_b(FieldOperand(ecx, SharedFunctionInfo::kNativeByteOffset),
- 1 << SharedFunctionInfo::kNativeBitWithinByte);
- __ j(not_equal, &cont);
+ EmitContinueIfStrictOrNative(masm, &cont);
}
// Load the receiver from the stack.
@@ -2425,50 +2401,13 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
if (NeedsChecks()) {
// Slow-case: Non-function called.
__ bind(&slow);
- if (RecordCallTarget()) {
- // If there is a call target cache, mark it megamorphic in the
- // non-function case. MegamorphicSentinel is an immortal immovable
- // object (megamorphic symbol) so no write barrier is needed.
- __ mov(FieldOperand(ebx, edx, times_half_pointer_size,
- FixedArray::kHeaderSize),
- Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate)));
- }
- // Check for function proxy.
- __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE);
- __ j(not_equal, &non_function);
- __ pop(ecx);
- __ push(edi); // put proxy as additional argument under return address
- __ push(ecx);
- __ Move(eax, Immediate(argc_ + 1));
- __ Move(ebx, Immediate(0));
- __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
- {
- Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline();
- __ jmp(adaptor, RelocInfo::CODE_TARGET);
- }
-
- // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
- // of the original receiver from the call site).
- __ bind(&non_function);
- __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi);
- __ Move(eax, Immediate(argc_));
- __ Move(ebx, Immediate(0));
- __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
- Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline();
- __ jmp(adaptor, RelocInfo::CODE_TARGET);
+ // (non_function is bound in EmitSlowCase)
+ EmitSlowCase(isolate(), masm, argc_, &non_function);
}
if (CallAsMethod()) {
__ bind(&wrap);
- // Wrap the receiver and patch it back onto the stack.
- { FrameScope frame_scope(masm, StackFrame::INTERNAL);
- __ push(edi);
- __ push(eax);
- __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
- __ pop(edi);
- }
- __ mov(Operand(esp, (argc_ + 1) * kPointerSize), eax);
- __ jmp(&cont);
+ EmitWrapCase(masm, argc_, &cont);
}
}
@@ -2502,10 +2441,10 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
__ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size,
FixedArray::kHeaderSize));
Handle<Map> allocation_site_map =
- masm->isolate()->factory()->allocation_site_map();
+ isolate()->factory()->allocation_site_map();
__ cmp(FieldOperand(ebx, 0), Immediate(allocation_site_map));
__ j(equal, &feedback_register_initialized);
- __ mov(ebx, masm->isolate()->factory()->undefined_value());
+ __ mov(ebx, isolate()->factory()->undefined_value());
__ bind(&feedback_register_initialized);
}
@@ -2536,11 +2475,123 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
// Set expected number of arguments to zero (not changing eax).
__ Move(ebx, Immediate(0));
Handle<Code> arguments_adaptor =
- masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
+ isolate()->builtins()->ArgumentsAdaptorTrampoline();
__ jmp(arguments_adaptor, RelocInfo::CODE_TARGET);
}
+static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
+ __ mov(vector, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
+ __ mov(vector, FieldOperand(vector, JSFunction::kSharedFunctionInfoOffset));
+ __ mov(vector, FieldOperand(vector,
+ SharedFunctionInfo::kFeedbackVectorOffset));
+}
+
+
+void CallICStub::Generate(MacroAssembler* masm) {
+ // edi - function
+ // edx - slot id
+ Isolate* isolate = masm->isolate();
+ Label extra_checks_or_miss, slow_start;
+ Label slow, non_function, wrap, cont;
+ Label have_js_function;
+ int argc = state_.arg_count();
+ ParameterCount actual(argc);
+
+ EmitLoadTypeFeedbackVector(masm, ebx);
+
+ // The checks. First, does edi match the recorded monomorphic target?
+ __ cmp(edi, FieldOperand(ebx, edx, times_half_pointer_size,
+ FixedArray::kHeaderSize));
+ __ j(not_equal, &extra_checks_or_miss);
+
+ __ bind(&have_js_function);
+ if (state_.CallAsMethod()) {
+ EmitContinueIfStrictOrNative(masm, &cont);
+
+ // Load the receiver from the stack.
+ __ mov(eax, Operand(esp, (argc + 1) * kPointerSize));
+
+ __ JumpIfSmi(eax, &wrap);
+
+ __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
+ __ j(below, &wrap);
+
+ __ bind(&cont);
+ }
+
+ __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper());
+
+ __ bind(&slow);
+ EmitSlowCase(isolate, masm, argc, &non_function);
+
+ if (state_.CallAsMethod()) {
+ __ bind(&wrap);
+ EmitWrapCase(masm, argc, &cont);
+ }
+
+ __ bind(&extra_checks_or_miss);
+ Label miss;
+
+ __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
+ FixedArray::kHeaderSize));
+ __ cmp(ecx, Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate)));
+ __ j(equal, &slow_start);
+ __ cmp(ecx, Immediate(TypeFeedbackInfo::UninitializedSentinel(isolate)));
+ __ j(equal, &miss);
+
+ if (!FLAG_trace_ic) {
+ // We are going megamorphic, and we don't want to visit the runtime.
+ __ mov(FieldOperand(ebx, edx, times_half_pointer_size,
+ FixedArray::kHeaderSize),
+ Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate)));
+ __ jmp(&slow_start);
+ }
+
+ // We are here because tracing is on or we are going monomorphic.
+ __ bind(&miss);
+ GenerateMiss(masm);
+
+ // the slow case
+ __ bind(&slow_start);
+
+ // Check that the function really is a JavaScript function.
+ __ JumpIfSmi(edi, &non_function);
+
+ // Goto slow case if we do not have a function.
+ __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
+ __ j(not_equal, &slow);
+ __ jmp(&have_js_function);
+
+ // Unreachable
+ __ int3();
+}
+
+
+void CallICStub::GenerateMiss(MacroAssembler* masm) {
+ // Get the receiver of the function from the stack; 1 ~ return address.
+ __ mov(ecx, Operand(esp, (state_.arg_count() + 1) * kPointerSize));
+
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+
+ // Push the receiver and the function and feedback info.
+ __ push(ecx);
+ __ push(edi);
+ __ push(ebx);
+ __ push(edx);
+
+ // Call the entry.
+ ExternalReference miss = ExternalReference(IC_Utility(IC::kCallIC_Miss),
+ masm->isolate());
+ __ CallExternalReference(miss, 4);
+
+ // Move result to edi and exit the internal frame.
+ __ mov(edi, eax);
+ }
+}
+
+
bool CEntryStub::NeedsImmovableCode() {
return false;
}
@@ -2553,8 +2604,8 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
// It is important that the store buffer overflow stubs are generated first.
ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
- if (Serializer::enabled()) {
- PlatformFeatureScope sse2(SSE2);
+ if (Serializer::enabled(isolate)) {
+ PlatformFeatureScope sse2(isolate, SSE2);
BinaryOpICStub::GenerateAheadOfTime(isolate);
BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
} else {
@@ -2566,12 +2617,12 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
void CodeStub::GenerateFPStubs(Isolate* isolate) {
if (CpuFeatures::IsSupported(SSE2)) {
- CEntryStub save_doubles(1, kSaveFPRegs);
+ CEntryStub save_doubles(isolate, 1, kSaveFPRegs);
// Stubs might already be in the snapshot, detect that and don't regenerate,
// which would lead to code stub initialization state being messed up.
Code* save_doubles_code;
- if (!save_doubles.FindCodeInCache(&save_doubles_code, isolate)) {
- save_doubles_code = *(save_doubles.GetCode(isolate));
+ if (!save_doubles.FindCodeInCache(&save_doubles_code)) {
+ save_doubles_code = *(save_doubles.GetCode());
}
isolate->set_fp_stubs_generated(true);
}
@@ -2579,17 +2630,24 @@ void CodeStub::GenerateFPStubs(Isolate* isolate) {
void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
- CEntryStub stub(1, kDontSaveFPRegs);
- stub.GetCode(isolate);
+ CEntryStub stub(isolate, 1, kDontSaveFPRegs);
+ stub.GetCode();
}
-void CEntryStub::GenerateCore(MacroAssembler* masm,
- Label* throw_normal_exception,
- Label* throw_termination_exception,
- bool do_gc,
- bool always_allocate_scope) {
- // eax: result parameter for PerformGC, if any
+void CEntryStub::Generate(MacroAssembler* masm) {
+ // eax: number of arguments including receiver
+ // ebx: pointer to C function (C callee-saved)
+ // ebp: frame pointer (restored after C call)
+ // esp: stack pointer (restored after C call)
+ // esi: current context (C callee-saved)
+ // edi: JS function of the caller (C callee-saved)
+
+ ProfileEntryHookStub::MaybeCallEntryHook(masm);
+
+ // Enter the exit frame that transitions from JavaScript to C++.
+ __ EnterExitFrame(save_doubles_ == kSaveFPRegs);
+
// ebx: pointer to C function (C callee-saved)
// ebp: frame pointer (restored after C call)
// esp: stack pointer (restored after C call)
@@ -2603,62 +2661,37 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
__ CheckStackAlignment();
}
- if (do_gc) {
- // Pass failure code returned from last attempt as first argument to
- // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the
- // stack alignment is known to be correct. This function takes one argument
- // which is passed on the stack, and we know that the stack has been
- // prepared to pass at least one argument.
- __ mov(Operand(esp, 1 * kPointerSize),
- Immediate(ExternalReference::isolate_address(masm->isolate())));
- __ mov(Operand(esp, 0 * kPointerSize), eax); // Result.
- __ call(FUNCTION_ADDR(Runtime::PerformGC), RelocInfo::RUNTIME_ENTRY);
- }
-
- ExternalReference scope_depth =
- ExternalReference::heap_always_allocate_scope_depth(masm->isolate());
- if (always_allocate_scope) {
- __ inc(Operand::StaticVariable(scope_depth));
- }
-
// Call C function.
__ mov(Operand(esp, 0 * kPointerSize), edi); // argc.
__ mov(Operand(esp, 1 * kPointerSize), esi); // argv.
__ mov(Operand(esp, 2 * kPointerSize),
- Immediate(ExternalReference::isolate_address(masm->isolate())));
+ Immediate(ExternalReference::isolate_address(isolate())));
__ call(ebx);
// Result is in eax or edx:eax - do not destroy these registers!
- if (always_allocate_scope) {
- __ dec(Operand::StaticVariable(scope_depth));
- }
-
// Runtime functions should not return 'the hole'. Allowing it to escape may
// lead to crashes in the IC code later.
if (FLAG_debug_code) {
Label okay;
- __ cmp(eax, masm->isolate()->factory()->the_hole_value());
+ __ cmp(eax, isolate()->factory()->the_hole_value());
__ j(not_equal, &okay, Label::kNear);
__ int3();
__ bind(&okay);
}
- // Check for failure result.
- Label failure_returned;
- STATIC_ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0);
- __ lea(ecx, Operand(eax, 1));
- // Lower 2 bits of ecx are 0 iff eax has failure tag.
- __ test(ecx, Immediate(kFailureTagMask));
- __ j(zero, &failure_returned);
+ // Check result for exception sentinel.
+ Label exception_returned;
+ __ cmp(eax, isolate()->factory()->exception());
+ __ j(equal, &exception_returned);
ExternalReference pending_exception_address(
- Isolate::kPendingExceptionAddress, masm->isolate());
+ Isolate::kPendingExceptionAddress, isolate());
// Check that there is no pending exception, otherwise we
- // should have returned some failure value.
+ // should have returned the exception sentinel.
if (FLAG_debug_code) {
__ push(edx);
- __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value()));
+ __ mov(edx, Immediate(isolate()->factory()->the_hole_value()));
Label okay;
__ cmp(edx, Operand::StaticVariable(pending_exception_address));
// Cannot use check here as it attempts to generate call into runtime.
@@ -2672,96 +2705,27 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
__ LeaveExitFrame(save_doubles_ == kSaveFPRegs);
__ ret(0);
- // Handling of failure.
- __ bind(&failure_returned);
-
- Label retry;
- // If the returned exception is RETRY_AFTER_GC continue at retry label
- STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0);
- __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize));
- __ j(zero, &retry, Label::kNear);
+ // Handling of exception.
+ __ bind(&exception_returned);
// Retrieve the pending exception.
__ mov(eax, Operand::StaticVariable(pending_exception_address));
// Clear the pending exception.
- __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value()));
+ __ mov(edx, Immediate(isolate()->factory()->the_hole_value()));
__ mov(Operand::StaticVariable(pending_exception_address), edx);
// Special handling of termination exceptions which are uncatchable
// by javascript code.
- __ cmp(eax, masm->isolate()->factory()->termination_exception());
- __ j(equal, throw_termination_exception);
-
- // Handle normal exception.
- __ jmp(throw_normal_exception);
-
- // Retry.
- __ bind(&retry);
-}
-
-
-void CEntryStub::Generate(MacroAssembler* masm) {
- // eax: number of arguments including receiver
- // ebx: pointer to C function (C callee-saved)
- // ebp: frame pointer (restored after C call)
- // esp: stack pointer (restored after C call)
- // esi: current context (C callee-saved)
- // edi: JS function of the caller (C callee-saved)
-
- ProfileEntryHookStub::MaybeCallEntryHook(masm);
-
- // NOTE: Invocations of builtins may return failure objects instead
- // of a proper result. The builtin entry handles this by performing
- // a garbage collection and retrying the builtin (twice).
-
- // Enter the exit frame that transitions from JavaScript to C++.
- __ EnterExitFrame(save_doubles_ == kSaveFPRegs);
-
- // eax: result parameter for PerformGC, if any (setup below)
- // ebx: pointer to builtin function (C callee-saved)
- // ebp: frame pointer (restored after C call)
- // esp: stack pointer (restored after C call)
- // edi: number of arguments including receiver (C callee-saved)
- // esi: argv pointer (C callee-saved)
-
- Label throw_normal_exception;
Label throw_termination_exception;
+ __ cmp(eax, isolate()->factory()->termination_exception());
+ __ j(equal, &throw_termination_exception);
- // Call into the runtime system.
- GenerateCore(masm,
- &throw_normal_exception,
- &throw_termination_exception,
- false,
- false);
-
- // Do space-specific GC and retry runtime call.
- GenerateCore(masm,
- &throw_normal_exception,
- &throw_termination_exception,
- true,
- false);
-
- // Do full GC and retry runtime call one final time.
- Failure* failure = Failure::InternalError();
- __ mov(eax, Immediate(reinterpret_cast<int32_t>(failure)));
- GenerateCore(masm,
- &throw_normal_exception,
- &throw_termination_exception,
- true,
- true);
-
- { FrameScope scope(masm, StackFrame::MANUAL);
- __ PrepareCallCFunction(0, eax);
- __ CallCFunction(
- ExternalReference::out_of_memory_function(masm->isolate()), 0);
- }
+ // Handle normal exception.
+ __ Throw(eax);
__ bind(&throw_termination_exception);
__ ThrowUncatchable(eax);
-
- __ bind(&throw_normal_exception);
- __ Throw(eax);
}
@@ -2785,12 +2749,11 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
__ push(ebx);
// Save copies of the top frame descriptor on the stack.
- ExternalReference c_entry_fp(Isolate::kCEntryFPAddress, masm->isolate());
+ ExternalReference c_entry_fp(Isolate::kCEntryFPAddress, isolate());
__ push(Operand::StaticVariable(c_entry_fp));
// If this is the outermost JS call, set js_entry_sp value.
- ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress,
- masm->isolate());
+ ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate());
__ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0));
__ j(not_equal, &not_outermost_js, Label::kNear);
__ mov(Operand::StaticVariable(js_entry_sp), ebp);
@@ -2807,9 +2770,9 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// Caught exception: Store result (exception) in the pending exception
// field in the JSEnv and return a failure sentinel.
ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
- masm->isolate());
+ isolate());
__ mov(Operand::StaticVariable(pending_exception), eax);
- __ mov(eax, reinterpret_cast<int32_t>(Failure::Exception()));
+ __ mov(eax, Immediate(isolate()->factory()->exception()));
__ jmp(&exit);
// Invoke: Link this frame into the handler chain. There's only one
@@ -2818,7 +2781,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
__ PushTryHandler(StackHandler::JS_ENTRY, 0);
// Clear any pending exceptions.
- __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value()));
+ __ mov(edx, Immediate(isolate()->factory()->the_hole_value()));
__ mov(Operand::StaticVariable(pending_exception), edx);
// Fake a receiver (NULL).
@@ -2830,11 +2793,10 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// builtin stubs may not have been generated yet.
if (is_construct) {
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
- masm->isolate());
+ isolate());
__ mov(edx, Immediate(construct_entry));
} else {
- ExternalReference entry(Builtins::kJSEntryTrampoline,
- masm->isolate());
+ ExternalReference entry(Builtins::kJSEntryTrampoline, isolate());
__ mov(edx, Immediate(entry));
}
__ mov(edx, Operand(edx, 0)); // deref address
@@ -2854,8 +2816,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// Restore the top frame descriptor from the stack.
__ pop(Operand::StaticVariable(ExternalReference(
- Isolate::kCEntryFPAddress,
- masm->isolate())));
+ Isolate::kCEntryFPAddress, isolate())));
// Restore callee-saved registers (C calling conventions).
__ pop(ebx);
@@ -2968,7 +2929,7 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
__ bind(&loop);
__ cmp(scratch, prototype);
__ j(equal, &is_instance, Label::kNear);
- Factory* factory = masm->isolate()->factory();
+ Factory* factory = isolate()->factory();
__ cmp(scratch, Immediate(factory->null_value()));
__ j(equal, &is_not_instance, Label::kNear);
__ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
@@ -3285,7 +3246,7 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm,
Register character,
Register scratch) {
// hash = (seed + character) + ((seed + character) << 10);
- if (Serializer::enabled()) {
+ if (Serializer::enabled(masm->isolate())) {
__ LoadRoot(scratch, Heap::kHashSeedRootIndex);
__ SmiUntag(scratch);
__ add(scratch, character);
@@ -3380,7 +3341,7 @@ void SubStringStub::Generate(MacroAssembler* masm) {
// Longer than original string's length or negative: unsafe arguments.
__ j(above, &runtime);
// Return original string.
- Counters* counters = masm->isolate()->counters();
+ Counters* counters = isolate()->counters();
__ IncrementCounter(counters->sub_string_native(), 1);
__ ret(3 * kPointerSize);
__ bind(&not_original_string);
@@ -3402,7 +3363,7 @@ void SubStringStub::Generate(MacroAssembler* masm) {
__ test(ebx, Immediate(kIsIndirectStringMask));
__ j(zero, &seq_or_external_string, Label::kNear);
- Factory* factory = masm->isolate()->factory();
+ Factory* factory = isolate()->factory();
__ test(ebx, Immediate(kSlicedNotConsMask));
__ j(not_zero, &sliced_string, Label::kNear);
// Cons string. Check whether it is flat, then fetch first part.
@@ -3722,7 +3683,7 @@ void StringCompareStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(EQUAL == 0);
STATIC_ASSERT(kSmiTag == 0);
__ Move(eax, Immediate(Smi::FromInt(EQUAL)));
- __ IncrementCounter(masm->isolate()->counters()->string_compare_native(), 1);
+ __ IncrementCounter(isolate()->counters()->string_compare_native(), 1);
__ ret(2 * kPointerSize);
__ bind(&not_same);
@@ -3744,223 +3705,30 @@ void StringCompareStub::Generate(MacroAssembler* masm) {
}
-void ArrayPushStub::Generate(MacroAssembler* masm) {
- int argc = arguments_count();
-
- if (argc == 0) {
- // Noop, return the length.
- __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
- __ ret((argc + 1) * kPointerSize);
- return;
- }
-
- Isolate* isolate = masm->isolate();
-
- if (argc != 1) {
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- Label call_builtin, attempt_to_grow_elements, with_write_barrier;
-
- // Get the elements array of the object.
- __ mov(edi, FieldOperand(edx, JSArray::kElementsOffset));
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- // Check that the elements are in fast mode and writable.
- __ cmp(FieldOperand(edi, HeapObject::kMapOffset),
- isolate->factory()->fixed_array_map());
- __ j(not_equal, &call_builtin);
- }
-
- // Get the array's length into eax and calculate new length.
- __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
- STATIC_ASSERT(kSmiTagSize == 1);
- STATIC_ASSERT(kSmiTag == 0);
- __ add(eax, Immediate(Smi::FromInt(argc)));
-
- // Get the elements' length into ecx.
- __ mov(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
-
- // Check if we could survive without allocation.
- __ cmp(eax, ecx);
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- __ j(greater, &attempt_to_grow_elements);
-
- // Check if value is a smi.
- __ mov(ecx, Operand(esp, argc * kPointerSize));
- __ JumpIfNotSmi(ecx, &with_write_barrier);
-
- // Store the value.
- __ mov(FieldOperand(edi, eax, times_half_pointer_size,
- FixedArray::kHeaderSize - argc * kPointerSize),
- ecx);
- } else {
- __ j(greater, &call_builtin);
-
- __ mov(ecx, Operand(esp, argc * kPointerSize));
- __ StoreNumberToDoubleElements(
- ecx, edi, eax, ecx, xmm0, &call_builtin, true, argc * kDoubleSize);
- }
-
- // Save new length.
- __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
- __ ret((argc + 1) * kPointerSize);
-
- if (IsFastDoubleElementsKind(elements_kind())) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ bind(&with_write_barrier);
-
- if (IsFastSmiElementsKind(elements_kind())) {
- if (FLAG_trace_elements_transitions) __ jmp(&call_builtin);
-
- __ cmp(FieldOperand(ecx, HeapObject::kMapOffset),
- isolate->factory()->heap_number_map());
- __ j(equal, &call_builtin);
-
- ElementsKind target_kind = IsHoleyElementsKind(elements_kind())
- ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
- __ mov(ebx, ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX));
- __ mov(ebx, FieldOperand(ebx, GlobalObject::kNativeContextOffset));
- __ mov(ebx, ContextOperand(ebx, Context::JS_ARRAY_MAPS_INDEX));
- const int header_size = FixedArrayBase::kHeaderSize;
- // Verify that the object can be transitioned in place.
- const int origin_offset = header_size + elements_kind() * kPointerSize;
- __ mov(edi, FieldOperand(ebx, origin_offset));
- __ cmp(edi, FieldOperand(edx, HeapObject::kMapOffset));
- __ j(not_equal, &call_builtin);
-
- const int target_offset = header_size + target_kind * kPointerSize;
- __ mov(ebx, FieldOperand(ebx, target_offset));
- ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
- masm, DONT_TRACK_ALLOCATION_SITE, NULL);
- // Restore edi used as a scratch register for the write barrier used while
- // setting the map.
- __ mov(edi, FieldOperand(edx, JSArray::kElementsOffset));
- }
-
- // Save new length.
- __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
-
- // Store the value.
- __ lea(edx, FieldOperand(edi, eax, times_half_pointer_size,
- FixedArray::kHeaderSize - argc * kPointerSize));
- __ mov(Operand(edx, 0), ecx);
-
- __ RecordWrite(edi, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
-
- __ ret((argc + 1) * kPointerSize);
-
- __ bind(&attempt_to_grow_elements);
- if (!FLAG_inline_new) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ mov(ebx, Operand(esp, argc * kPointerSize));
- // Growing elements that are SMI-only requires special handling in case the
- // new element is non-Smi. For now, delegate to the builtin.
- if (IsFastSmiElementsKind(elements_kind())) {
- __ JumpIfNotSmi(ebx, &call_builtin);
- }
-
- // We could be lucky and the elements array could be at the top of new-space.
- // In this case we can just grow it in place by moving the allocation pointer
- // up.
- ExternalReference new_space_allocation_top =
- ExternalReference::new_space_allocation_top_address(isolate);
- ExternalReference new_space_allocation_limit =
- ExternalReference::new_space_allocation_limit_address(isolate);
-
- const int kAllocationDelta = 4;
- ASSERT(kAllocationDelta >= argc);
- // Load top.
- __ mov(ecx, Operand::StaticVariable(new_space_allocation_top));
-
- // Check if it's the end of elements.
- __ lea(edx, FieldOperand(edi, eax, times_half_pointer_size,
- FixedArray::kHeaderSize - argc * kPointerSize));
- __ cmp(edx, ecx);
- __ j(not_equal, &call_builtin);
- __ add(ecx, Immediate(kAllocationDelta * kPointerSize));
- __ cmp(ecx, Operand::StaticVariable(new_space_allocation_limit));
- __ j(above, &call_builtin);
-
- // We fit and could grow elements.
- __ mov(Operand::StaticVariable(new_space_allocation_top), ecx);
-
- // Push the argument...
- __ mov(Operand(edx, 0), ebx);
- // ... and fill the rest with holes.
- for (int i = 1; i < kAllocationDelta; i++) {
- __ mov(Operand(edx, i * kPointerSize),
- isolate->factory()->the_hole_value());
- }
-
- if (IsFastObjectElementsKind(elements_kind())) {
- // We know the elements array is in new space so we don't need the
- // remembered set, but we just pushed a value onto it so we may have to tell
- // the incremental marker to rescan the object that we just grew. We don't
- // need to worry about the holes because they are in old space and already
- // marked black.
- __ RecordWrite(edi, edx, ebx, kDontSaveFPRegs, OMIT_REMEMBERED_SET);
- }
-
- // Restore receiver to edx as finish sequence assumes it's here.
- __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
-
- // Increment element's and array's sizes.
- __ add(FieldOperand(edi, FixedArray::kLengthOffset),
- Immediate(Smi::FromInt(kAllocationDelta)));
-
- // NOTE: This only happen in new-space, where we don't care about the
- // black-byte-count on pages. Otherwise we should update that too if the
- // object is black.
-
- __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
- __ ret((argc + 1) * kPointerSize);
-
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
-}
-
-
void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- edx : left
// -- eax : right
// -- esp[0] : return address
// -----------------------------------
- Isolate* isolate = masm->isolate();
// Load ecx with the allocation site. We stick an undefined dummy value here
// and replace it with the real allocation site later when we instantiate this
// stub in BinaryOpICWithAllocationSiteStub::GetCodeCopyFromTemplate().
- __ mov(ecx, handle(isolate->heap()->undefined_value()));
+ __ mov(ecx, handle(isolate()->heap()->undefined_value()));
// Make sure that we actually patched the allocation site.
if (FLAG_debug_code) {
__ test(ecx, Immediate(kSmiTagMask));
__ Assert(not_equal, kExpectedAllocationSite);
__ cmp(FieldOperand(ecx, HeapObject::kMapOffset),
- isolate->factory()->allocation_site_map());
+ isolate()->factory()->allocation_site_map());
__ Assert(equal, kExpectedAllocationSite);
}
// Tail call into the stub that handles binary operations with allocation
// sites.
- BinaryOpWithAllocationSiteStub stub(state_);
+ BinaryOpWithAllocationSiteStub stub(isolate(), state_);
__ TailCallStub(&stub);
}
@@ -4015,7 +3783,7 @@ void ICCompareStub::GenerateNumbers(MacroAssembler* masm) {
Label done, left, left_smi, right_smi;
__ JumpIfSmi(eax, &right_smi, Label::kNear);
__ cmp(FieldOperand(eax, HeapObject::kMapOffset),
- masm->isolate()->factory()->heap_number_map());
+ isolate()->factory()->heap_number_map());
__ j(not_equal, &maybe_undefined1, Label::kNear);
__ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
__ jmp(&left, Label::kNear);
@@ -4027,7 +3795,7 @@ void ICCompareStub::GenerateNumbers(MacroAssembler* masm) {
__ bind(&left);
__ JumpIfSmi(edx, &left_smi, Label::kNear);
__ cmp(FieldOperand(edx, HeapObject::kMapOffset),
- masm->isolate()->factory()->heap_number_map());
+ isolate()->factory()->heap_number_map());
__ j(not_equal, &maybe_undefined2, Label::kNear);
__ movsd(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
__ jmp(&done);
@@ -4057,22 +3825,22 @@ void ICCompareStub::GenerateNumbers(MacroAssembler* masm) {
__ JumpIfSmi(ecx, &generic_stub, Label::kNear);
__ cmp(FieldOperand(eax, HeapObject::kMapOffset),
- masm->isolate()->factory()->heap_number_map());
+ isolate()->factory()->heap_number_map());
__ j(not_equal, &maybe_undefined1, Label::kNear);
__ cmp(FieldOperand(edx, HeapObject::kMapOffset),
- masm->isolate()->factory()->heap_number_map());
+ isolate()->factory()->heap_number_map());
__ j(not_equal, &maybe_undefined2, Label::kNear);
}
__ bind(&unordered);
__ bind(&generic_stub);
- ICCompareStub stub(op_, CompareIC::GENERIC, CompareIC::GENERIC,
+ ICCompareStub stub(isolate(), op_, CompareIC::GENERIC, CompareIC::GENERIC,
CompareIC::GENERIC);
- __ jmp(stub.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
+ __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
__ bind(&maybe_undefined1);
if (Token::IsOrderedRelationalCompareOp(op_)) {
- __ cmp(eax, Immediate(masm->isolate()->factory()->undefined_value()));
+ __ cmp(eax, Immediate(isolate()->factory()->undefined_value()));
__ j(not_equal, &miss);
__ JumpIfSmi(edx, &unordered);
__ CmpObjectType(edx, HEAP_NUMBER_TYPE, ecx);
@@ -4082,7 +3850,7 @@ void ICCompareStub::GenerateNumbers(MacroAssembler* masm) {
__ bind(&maybe_undefined2);
if (Token::IsOrderedRelationalCompareOp(op_)) {
- __ cmp(edx, Immediate(masm->isolate()->factory()->undefined_value()));
+ __ cmp(edx, Immediate(isolate()->factory()->undefined_value()));
__ j(equal, &unordered);
}
@@ -4317,7 +4085,7 @@ void ICCompareStub::GenerateMiss(MacroAssembler* masm) {
{
// Call the runtime system in a fresh internal frame.
ExternalReference miss = ExternalReference(IC_Utility(IC::kCompareIC_Miss),
- masm->isolate());
+ isolate());
FrameScope scope(masm, StackFrame::INTERNAL);
__ push(edx); // Preserve edx and eax.
__ push(eax);
@@ -4391,7 +4159,8 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
__ bind(&good);
}
- NameDictionaryLookupStub stub(properties, r0, r0, NEGATIVE_LOOKUP);
+ NameDictionaryLookupStub stub(masm->isolate(), properties, r0, r0,
+ NEGATIVE_LOOKUP);
__ push(Immediate(Handle<Object>(name)));
__ push(Immediate(name->Hash()));
__ CallStub(&stub);
@@ -4447,7 +4216,8 @@ void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
__ j(equal, done);
}
- NameDictionaryLookupStub stub(elements, r1, r0, POSITIVE_LOOKUP);
+ NameDictionaryLookupStub stub(masm->isolate(), elements, r1, r0,
+ POSITIVE_LOOKUP);
__ push(name);
__ mov(r0, FieldOperand(name, Name::kHashFieldOffset));
__ shr(r0, Name::kHashShift);
@@ -4507,7 +4277,7 @@ void NameDictionaryLookupStub::Generate(MacroAssembler* masm) {
index_,
times_pointer_size,
kElementsStartOffset - kHeapObjectTag));
- __ cmp(scratch, masm->isolate()->factory()->undefined_value());
+ __ cmp(scratch, isolate()->factory()->undefined_value());
__ j(equal, &not_in_dictionary);
// Stop if found the property.
@@ -4550,11 +4320,11 @@ void NameDictionaryLookupStub::Generate(MacroAssembler* masm) {
void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
Isolate* isolate) {
- StoreBufferOverflowStub stub(kDontSaveFPRegs);
- stub.GetCode(isolate);
- if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
- StoreBufferOverflowStub stub2(kSaveFPRegs);
- stub2.GetCode(isolate);
+ StoreBufferOverflowStub stub(isolate, kDontSaveFPRegs);
+ stub.GetCode();
+ if (CpuFeatures::IsSafeForSnapshot(isolate, SSE2)) {
+ StoreBufferOverflowStub stub2(isolate, kSaveFPRegs);
+ stub2.GetCode();
}
}
@@ -4653,12 +4423,11 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
__ mov(Operand(esp, 0 * kPointerSize), regs_.object());
__ mov(Operand(esp, 1 * kPointerSize), regs_.address()); // Slot.
__ mov(Operand(esp, 2 * kPointerSize),
- Immediate(ExternalReference::isolate_address(masm->isolate())));
+ Immediate(ExternalReference::isolate_address(isolate())));
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(
- ExternalReference::incremental_marking_record_write_function(
- masm->isolate()),
+ ExternalReference::incremental_marking_record_write_function(isolate()),
argument_count);
regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode_);
@@ -4845,8 +4614,8 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
- CEntryStub ces(1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
- __ call(ces.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
+ CEntryStub ces(isolate(), 1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
+ __ call(ces.GetCode(), RelocInfo::CODE_TARGET);
int parameter_count_offset =
StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
__ mov(ebx, MemOperand(ebp, parameter_count_offset));
@@ -4862,7 +4631,7 @@ void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
if (masm->isolate()->function_entry_hook() != NULL) {
- ProfileEntryHookStub stub;
+ ProfileEntryHookStub stub(masm->isolate());
masm->CallStub(&stub);
}
}
@@ -4886,8 +4655,8 @@ void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
__ push(eax);
// Call the entry hook.
- ASSERT(masm->isolate()->function_entry_hook() != NULL);
- __ call(FUNCTION_ADDR(masm->isolate()->function_entry_hook()),
+ ASSERT(isolate()->function_entry_hook() != NULL);
+ __ call(FUNCTION_ADDR(isolate()->function_entry_hook()),
RelocInfo::RUNTIME_ENTRY);
__ add(esp, Immediate(2 * kPointerSize));
@@ -4904,7 +4673,8 @@ template<class T>
static void CreateArrayDispatch(MacroAssembler* masm,
AllocationSiteOverrideMode mode) {
if (mode == DISABLE_ALLOCATION_SITES) {
- T stub(GetInitialFastElementsKind(),
+ T stub(masm->isolate(),
+ GetInitialFastElementsKind(),
mode);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
@@ -4915,7 +4685,7 @@ static void CreateArrayDispatch(MacroAssembler* masm,
ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
__ cmp(edx, kind);
__ j(not_equal, &next);
- T stub(kind);
+ T stub(masm->isolate(), kind);
__ TailCallStub(&stub);
__ bind(&next);
}
@@ -4959,12 +4729,14 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
ElementsKind initial = GetInitialFastElementsKind();
ElementsKind holey_initial = GetHoleyElementsKind(initial);
- ArraySingleArgumentConstructorStub stub_holey(holey_initial,
+ ArraySingleArgumentConstructorStub stub_holey(masm->isolate(),
+ holey_initial,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub_holey);
__ bind(&normal_sequence);
- ArraySingleArgumentConstructorStub stub(initial,
+ ArraySingleArgumentConstructorStub stub(masm->isolate(),
+ initial,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
@@ -4994,7 +4766,7 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
__ cmp(edx, kind);
__ j(not_equal, &next);
- ArraySingleArgumentConstructorStub stub(kind);
+ ArraySingleArgumentConstructorStub stub(masm->isolate(), kind);
__ TailCallStub(&stub);
__ bind(&next);
}
@@ -5013,11 +4785,11 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
TERMINAL_FAST_ELEMENTS_KIND);
for (int i = 0; i <= to_index; ++i) {
ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
- T stub(kind);
- stub.GetCode(isolate);
+ T stub(isolate, kind);
+ stub.GetCode();
if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
- T stub1(kind, DISABLE_ALLOCATION_SITES);
- stub1.GetCode(isolate);
+ T stub1(isolate, kind, DISABLE_ALLOCATION_SITES);
+ stub1.GetCode();
}
}
}
@@ -5038,12 +4810,12 @@ void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
for (int i = 0; i < 2; i++) {
// For internal arrays we only need a few things
- InternalArrayNoArgumentConstructorStub stubh1(kinds[i]);
- stubh1.GetCode(isolate);
- InternalArraySingleArgumentConstructorStub stubh2(kinds[i]);
- stubh2.GetCode(isolate);
- InternalArrayNArgumentsConstructorStub stubh3(kinds[i]);
- stubh3.GetCode(isolate);
+ InternalArrayNoArgumentConstructorStub stubh1(isolate, kinds[i]);
+ stubh1.GetCode();
+ InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]);
+ stubh2.GetCode();
+ InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]);
+ stubh3.GetCode();
}
}
@@ -5103,7 +4875,7 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
Label no_info;
// If the feedback vector is the undefined value call an array constructor
// that doesn't use AllocationSites.
- __ cmp(ebx, masm->isolate()->factory()->undefined_value());
+ __ cmp(ebx, isolate()->factory()->undefined_value());
__ j(equal, &no_info);
// Only look at the lower 16 bits of the transition info.
@@ -5125,7 +4897,7 @@ void InternalArrayConstructorStub::GenerateCase(
__ test(eax, eax);
__ j(not_zero, &not_zero_case);
- InternalArrayNoArgumentConstructorStub stub0(kind);
+ InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
__ TailCallStub(&stub0);
__ bind(&not_zero_case);
@@ -5140,16 +4912,16 @@ void InternalArrayConstructorStub::GenerateCase(
__ j(zero, &normal_sequence);
InternalArraySingleArgumentConstructorStub
- stub1_holey(GetHoleyElementsKind(kind));
+ stub1_holey(isolate(), GetHoleyElementsKind(kind));
__ TailCallStub(&stub1_holey);
}
__ bind(&normal_sequence);
- InternalArraySingleArgumentConstructorStub stub1(kind);
+ InternalArraySingleArgumentConstructorStub stub1(isolate(), kind);
__ TailCallStub(&stub1);
__ bind(&not_one_case);
- InternalArrayNArgumentsConstructorStub stubN(kind);
+ InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
__ TailCallStub(&stubN);
}
@@ -5242,8 +5014,6 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(FCA::kHolderIndex == 0);
STATIC_ASSERT(FCA::kArgsLength == 7);
- Isolate* isolate = masm->isolate();
-
__ pop(return_address);
// context save
@@ -5260,9 +5030,9 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
Register scratch = call_data;
if (!call_data_undefined) {
// return value
- __ push(Immediate(isolate->factory()->undefined_value()));
+ __ push(Immediate(isolate()->factory()->undefined_value()));
// return value default
- __ push(Immediate(isolate->factory()->undefined_value()));
+ __ push(Immediate(isolate()->factory()->undefined_value()));
} else {
// return value
__ push(scratch);
@@ -5270,7 +5040,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
__ push(scratch);
}
// isolate
- __ push(Immediate(reinterpret_cast<int>(isolate)));
+ __ push(Immediate(reinterpret_cast<int>(isolate())));
// holder
__ push(holder);
@@ -5305,7 +5075,8 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
__ lea(scratch, ApiParameterOperand(2));
__ mov(ApiParameterOperand(0), scratch);
- Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
+ ExternalReference thunk_ref =
+ ExternalReference::invoke_function_callback(isolate());
Operand context_restore_operand(ebp,
(2 + FCA::kContextSaveIndex) * kPointerSize);
@@ -5318,7 +5089,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
}
Operand return_value_operand(ebp, return_value_offset * kPointerSize);
__ CallApiFunctionAndReturn(api_function_address,
- thunk_address,
+ thunk_ref,
ApiParameterOperand(1),
argc + FCA::kArgsLength + 1,
return_value_operand,
@@ -5353,10 +5124,11 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
__ add(scratch, Immediate(kPointerSize));
__ mov(ApiParameterOperand(1), scratch); // arguments pointer.
- Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+ ExternalReference thunk_ref =
+ ExternalReference::invoke_accessor_getter_callback(isolate());
__ CallApiFunctionAndReturn(api_function_address,
- thunk_address,
+ thunk_ref,
ApiParameterOperand(2),
kStackSpace,
Operand(ebp, 7 * kPointerSize),
diff --git a/deps/v8/src/ia32/code-stubs-ia32.h b/deps/v8/src/ia32/code-stubs-ia32.h
index cf20a11c6d..1d55ec3c02 100644
--- a/deps/v8/src/ia32/code-stubs-ia32.h
+++ b/deps/v8/src/ia32/code-stubs-ia32.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_IA32_CODE_STUBS_IA32_H_
#define V8_IA32_CODE_STUBS_IA32_H_
@@ -42,9 +19,10 @@ void ArrayNativeCode(MacroAssembler* masm,
class StoreBufferOverflowStub: public PlatformCodeStub {
public:
- explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp)
- : save_doubles_(save_fp) {
- ASSERT(CpuFeatures::IsSafeForSnapshot(SSE2) || save_fp == kDontSaveFPRegs);
+ StoreBufferOverflowStub(Isolate* isolate, SaveFPRegsMode save_fp)
+ : PlatformCodeStub(isolate), save_doubles_(save_fp) {
+ ASSERT(CpuFeatures::IsSafeForSnapshot(isolate, SSE2) ||
+ save_fp == kDontSaveFPRegs);
}
void Generate(MacroAssembler* masm);
@@ -92,7 +70,7 @@ class StringHelper : public AllStatic {
class SubStringStub: public PlatformCodeStub {
public:
- SubStringStub() {}
+ explicit SubStringStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
private:
Major MajorKey() { return SubString; }
@@ -104,7 +82,7 @@ class SubStringStub: public PlatformCodeStub {
class StringCompareStub: public PlatformCodeStub {
public:
- StringCompareStub() { }
+ explicit StringCompareStub(Isolate* isolate) : PlatformCodeStub(isolate) { }
// Compares two flat ASCII strings and returns result in eax.
static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
@@ -142,11 +120,13 @@ class NameDictionaryLookupStub: public PlatformCodeStub {
public:
enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
- NameDictionaryLookupStub(Register dictionary,
+ NameDictionaryLookupStub(Isolate* isolate,
+ Register dictionary,
Register result,
Register index,
LookupMode mode)
- : dictionary_(dictionary), result_(result), index_(index), mode_(mode) { }
+ : PlatformCodeStub(isolate),
+ dictionary_(dictionary), result_(result), index_(index), mode_(mode) { }
void Generate(MacroAssembler* masm);
@@ -202,12 +182,14 @@ class NameDictionaryLookupStub: public PlatformCodeStub {
class RecordWriteStub: public PlatformCodeStub {
public:
- RecordWriteStub(Register object,
+ RecordWriteStub(Isolate* isolate,
+ Register object,
Register value,
Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode)
- : object_(object),
+ : PlatformCodeStub(isolate),
+ object_(object),
value_(value),
address_(address),
remembered_set_action_(remembered_set_action),
@@ -215,7 +197,8 @@ class RecordWriteStub: public PlatformCodeStub {
regs_(object, // An input reg.
address, // An input reg.
value) { // One scratch reg.
- ASSERT(CpuFeatures::IsSafeForSnapshot(SSE2) || fp_mode == kDontSaveFPRegs);
+ ASSERT(CpuFeatures::IsSafeForSnapshot(isolate, SSE2) ||
+ fp_mode == kDontSaveFPRegs);
}
enum Mode {
diff --git a/deps/v8/src/ia32/codegen-ia32.cc b/deps/v8/src/ia32/codegen-ia32.cc
index 350a8fb224..19b66aee3b 100644
--- a/deps/v8/src/ia32/codegen-ia32.cc
+++ b/deps/v8/src/ia32/codegen-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -1073,37 +1050,33 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
#undef __
-static byte* GetNoCodeAgeSequence(uint32_t* length) {
- static bool initialized = false;
- static byte sequence[kNoCodeAgeSequenceLength];
- *length = kNoCodeAgeSequenceLength;
- if (!initialized) {
- // The sequence of instructions that is patched out for aging code is the
- // following boilerplate stack-building prologue that is found both in
- // FUNCTION and OPTIMIZED_FUNCTION code:
- CodePatcher patcher(sequence, kNoCodeAgeSequenceLength);
- patcher.masm()->push(ebp);
- patcher.masm()->mov(ebp, esp);
- patcher.masm()->push(esi);
- patcher.masm()->push(edi);
- initialized = true;
- }
- return sequence;
+CodeAgingHelper::CodeAgingHelper() {
+ ASSERT(young_sequence_.length() == kNoCodeAgeSequenceLength);
+ CodePatcher patcher(young_sequence_.start(), young_sequence_.length());
+ patcher.masm()->push(ebp);
+ patcher.masm()->mov(ebp, esp);
+ patcher.masm()->push(esi);
+ patcher.masm()->push(edi);
+}
+
+
+#ifdef DEBUG
+bool CodeAgingHelper::IsOld(byte* candidate) const {
+ return *candidate == kCallOpcode;
}
+#endif
-bool Code::IsYoungSequence(byte* sequence) {
- uint32_t young_length;
- byte* young_sequence = GetNoCodeAgeSequence(&young_length);
- bool result = (!memcmp(sequence, young_sequence, young_length));
- ASSERT(result || *sequence == kCallOpcode);
+bool Code::IsYoungSequence(Isolate* isolate, byte* sequence) {
+ bool result = isolate->code_aging_helper()->IsYoung(sequence);
+ ASSERT(result || isolate->code_aging_helper()->IsOld(sequence));
return result;
}
-void Code::GetCodeAgeAndParity(byte* sequence, Age* age,
+void Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
MarkingParity* parity) {
- if (IsYoungSequence(sequence)) {
+ if (IsYoungSequence(isolate, sequence)) {
*age = kNoAgeCodeAge;
*parity = NO_MARKING_PARITY;
} else {
@@ -1120,10 +1093,9 @@ void Code::PatchPlatformCodeAge(Isolate* isolate,
byte* sequence,
Code::Age age,
MarkingParity parity) {
- uint32_t young_length;
- byte* young_sequence = GetNoCodeAgeSequence(&young_length);
+ uint32_t young_length = isolate->code_aging_helper()->young_sequence_length();
if (age == kNoAgeCodeAge) {
- CopyBytes(sequence, young_sequence, young_length);
+ isolate->code_aging_helper()->CopyYoungSequenceTo(sequence);
CPU::FlushICache(sequence, young_length);
} else {
Code* stub = GetCodeAgeStub(isolate, age, parity);
diff --git a/deps/v8/src/ia32/codegen-ia32.h b/deps/v8/src/ia32/codegen-ia32.h
index 2ef8043078..eda92b0a8c 100644
--- a/deps/v8/src/ia32/codegen-ia32.h
+++ b/deps/v8/src/ia32/codegen-ia32.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_IA32_CODEGEN_IA32_H_
#define V8_IA32_CODEGEN_IA32_H_
diff --git a/deps/v8/src/ia32/cpu-ia32.cc b/deps/v8/src/ia32/cpu-ia32.cc
index 5fb04fc727..7f87a624e3 100644
--- a/deps/v8/src/ia32/cpu-ia32.cc
+++ b/deps/v8/src/ia32/cpu-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// CPU specific code for ia32 independent of OS goes here.
@@ -41,16 +18,6 @@
namespace v8 {
namespace internal {
-void CPU::SetUp() {
- CpuFeatures::Probe();
-}
-
-
-bool CPU::SupportsCrankshaft() {
- return CpuFeatures::IsSupported(SSE2);
-}
-
-
void CPU::FlushICache(void* start, size_t size) {
// No need to flush the instruction cache on Intel. On Intel instruction
// cache flushing is only necessary when multiple cores running the same
diff --git a/deps/v8/src/ia32/debug-ia32.cc b/deps/v8/src/ia32/debug-ia32.cc
index 42284ec75c..e7a7b60581 100644
--- a/deps/v8/src/ia32/debug-ia32.cc
+++ b/deps/v8/src/ia32/debug-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -36,8 +13,6 @@
namespace v8 {
namespace internal {
-#ifdef ENABLE_DEBUGGER_SUPPORT
-
bool BreakLocationIterator::IsDebugBreakAtReturn() {
return Debug::IsDebugBreakAtReturn(rinfo());
}
@@ -50,7 +25,7 @@ void BreakLocationIterator::SetDebugBreakAtReturn() {
ASSERT(Assembler::kJSReturnSequenceLength >=
Assembler::kCallInstructionLength);
rinfo()->PatchCodeWithCall(
- debug_info_->GetIsolate()->debug()->debug_break_return()->entry(),
+ debug_info_->GetIsolate()->builtins()->Return_DebugBreak()->entry(),
Assembler::kJSReturnSequenceLength - Assembler::kCallInstructionLength);
}
@@ -81,7 +56,7 @@ void BreakLocationIterator::SetDebugBreakAtSlot() {
ASSERT(IsDebugBreakSlot());
Isolate* isolate = debug_info_->GetIsolate();
rinfo()->PatchCodeWithCall(
- isolate->debug()->debug_break_slot()->entry(),
+ isolate->builtins()->Slot_DebugBreak()->entry(),
Assembler::kDebugBreakSlotLength - Assembler::kCallInstructionLength);
}
@@ -141,7 +116,7 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
__ Move(eax, Immediate(0)); // No arguments.
__ mov(ebx, Immediate(ExternalReference::debug_break(masm->isolate())));
- CEntryStub ceb(1);
+ CEntryStub ceb(masm->isolate(), 1);
__ CallStub(&ceb);
// Automatically find register that could be used after register restore.
@@ -197,6 +172,17 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
}
+void Debug::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
+ // Register state for CallICStub
+ // ----------- S t a t e -------------
+ // -- edx : type feedback slot (smi)
+ // -- edi : function
+ // -----------------------------------
+ Generate_DebugBreakCallHelper(masm, edx.bit() | edi.bit(),
+ 0, false);
+}
+
+
void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Register state for IC load call (from ic-ia32.cc).
// ----------- S t a t e -------------
@@ -250,15 +236,6 @@ void Debug::GenerateCompareNilICDebugBreak(MacroAssembler* masm) {
}
-void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) {
- // Register state for keyed IC call call (from ic-ia32.cc)
- // ----------- S t a t e -------------
- // -- ecx: name
- // -----------------------------------
- Generate_DebugBreakCallHelper(masm, ecx.bit(), 0, false);
-}
-
-
void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
// Register state just before return from JS function (from codegen-ia32.cc).
// ----------- S t a t e -------------
@@ -277,18 +254,6 @@ void Debug::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
}
-void Debug::GenerateCallFunctionStubRecordDebugBreak(MacroAssembler* masm) {
- // Register state for CallFunctionStub (from code-stubs-ia32.cc).
- // ----------- S t a t e -------------
- // -- ebx: feedback array
- // -- edx: slot in feedback array
- // -- edi: function
- // -----------------------------------
- Generate_DebugBreakCallHelper(masm, ebx.bit() | edx.bit() | edi.bit(),
- 0, false);
-}
-
-
void Debug::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
// Register state for CallConstructStub (from code-stubs-ia32.cc).
// eax is the actual number of arguments not encoded as a smi see comment
@@ -369,8 +334,6 @@ const bool Debug::kFrameDropperSupported = true;
#undef __
-#endif // ENABLE_DEBUGGER_SUPPORT
-
} } // namespace v8::internal
#endif // V8_TARGET_ARCH_IA32
diff --git a/deps/v8/src/ia32/deoptimizer-ia32.cc b/deps/v8/src/ia32/deoptimizer-ia32.cc
index 711cdf86fb..6db045079d 100644
--- a/deps/v8/src/ia32/deoptimizer-ia32.cc
+++ b/deps/v8/src/ia32/deoptimizer-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/ia32/disasm-ia32.cc b/deps/v8/src/ia32/disasm-ia32.cc
index e50a78e345..721b0bb429 100644
--- a/deps/v8/src/ia32/disasm-ia32.cc
+++ b/deps/v8/src/ia32/disasm-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <assert.h>
#include <stdio.h>
diff --git a/deps/v8/src/ia32/frames-ia32.cc b/deps/v8/src/ia32/frames-ia32.cc
index 9859ebb0e5..55671ba8fd 100644
--- a/deps/v8/src/ia32/frames-ia32.cc
+++ b/deps/v8/src/ia32/frames-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/ia32/frames-ia32.h b/deps/v8/src/ia32/frames-ia32.h
index 2d6145eeac..fcfabda8b6 100644
--- a/deps/v8/src/ia32/frames-ia32.h
+++ b/deps/v8/src/ia32/frames-ia32.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_IA32_FRAMES_IA32_H_
#define V8_IA32_FRAMES_IA32_H_
diff --git a/deps/v8/src/ia32/full-codegen-ia32.cc b/deps/v8/src/ia32/full-codegen-ia32.cc
index 70a968e8a2..63c3ee6014 100644
--- a/deps/v8/src/ia32/full-codegen-ia32.cc
+++ b/deps/v8/src/ia32/full-codegen-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -74,7 +51,7 @@ class JumpPatchSite BASE_EMBEDDED {
void EmitPatchInfo() {
if (patch_site_.is_bound()) {
int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site_);
- ASSERT(is_int8(delta_to_patch_site));
+ ASSERT(is_uint8(delta_to_patch_site));
__ test(eax, Immediate(delta_to_patch_site));
#ifdef DEBUG
info_emitted_ = true;
@@ -106,12 +83,14 @@ static void EmitStackCheck(MacroAssembler* masm_,
Register scratch = esp) {
Label ok;
Isolate* isolate = masm_->isolate();
- ExternalReference stack_limit =
- ExternalReference::address_of_stack_limit(isolate);
ASSERT(scratch.is(esp) == (pointers == 0));
+ ExternalReference stack_limit;
if (pointers != 0) {
__ mov(scratch, esp);
__ sub(scratch, Immediate(pointers * kPointerSize));
+ stack_limit = ExternalReference::address_of_real_stack_limit(isolate);
+ } else {
+ stack_limit = ExternalReference::address_of_stack_limit(isolate);
}
__ cmp(scratch, Operand::StaticVariable(stack_limit));
__ j(above_equal, &ok, Label::kNear);
@@ -138,8 +117,6 @@ void FullCodeGenerator::Generate() {
handler_table_ =
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
- InitializeFeedbackVector();
-
profiling_counter_ = isolate()->factory()->NewCell(
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
SetFunctionPosition(function());
@@ -227,7 +204,7 @@ void FullCodeGenerator::Generate() {
__ Push(info->scope()->GetScopeInfo());
__ CallRuntime(Runtime::kHiddenNewGlobalContext, 2);
} else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
- FastNewContextStub stub(heap_slots);
+ FastNewContextStub stub(isolate(), heap_slots);
__ CallStub(&stub);
} else {
__ push(edi);
@@ -289,7 +266,7 @@ void FullCodeGenerator::Generate() {
} else {
type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
}
- ArgumentsAccessStub stub(type);
+ ArgumentsAccessStub stub(isolate(), type);
__ CallStub(&stub);
SetVar(arguments, eax, ebx, edx);
@@ -434,12 +411,10 @@ void FullCodeGenerator::EmitReturnSequence() {
int arguments_bytes = (info_->scope()->num_parameters() + 1) * kPointerSize;
__ Ret(arguments_bytes, ecx);
-#ifdef ENABLE_DEBUGGER_SUPPORT
// Check that the size of the code used for returning is large enough
// for the debugger's requirements.
ASSERT(Assembler::kJSReturnSequenceLength <=
masm_->SizeOfCodeGeneratedSince(&check_exit_codesize));
-#endif
info_->AddNoFrameRange(no_frame_start, masm_->pc_offset());
}
}
@@ -1135,15 +1110,10 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Label non_proxy;
__ bind(&fixed_array);
- Handle<Object> feedback = Handle<Object>(
- Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
- isolate());
- StoreFeedbackVectorSlot(slot, feedback);
-
// No need for a write barrier, we are storing a Smi in the feedback vector.
__ LoadHeapObject(ebx, FeedbackVector());
__ mov(FieldOperand(ebx, FixedArray::OffsetOfElementAt(slot)),
- Immediate(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker)));
+ Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate())));
__ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check
__ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object
@@ -1298,7 +1268,9 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
!pretenure &&
scope()->is_function_scope() &&
info->num_literals() == 0) {
- FastNewClosureStub stub(info->strict_mode(), info->is_generator());
+ FastNewClosureStub stub(isolate(),
+ info->strict_mode(),
+ info->is_generator());
__ mov(ebx, Immediate(info));
__ CallStub(&stub);
} else {
@@ -1617,7 +1589,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
? ObjectLiteral::kHasFunction
: ObjectLiteral::kNoFlags;
int properties_count = constant_properties->length() / 2;
- if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() ||
+ if (expr->may_store_doubles() || expr->depth() > 1 ||
+ Serializer::enabled(isolate()) ||
flags != ObjectLiteral::kFastElements ||
properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
__ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
@@ -1632,7 +1605,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
__ mov(ebx, Immediate(Smi::FromInt(expr->literal_index())));
__ mov(ecx, Immediate(constant_properties));
__ mov(edx, Immediate(Smi::FromInt(flags)));
- FastCloneShallowObjectStub stub(properties_count);
+ FastCloneShallowObjectStub stub(isolate(), properties_count);
__ CallStub(&stub);
}
@@ -1767,11 +1740,12 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
__ mov(ebx, Immediate(Smi::FromInt(expr->literal_index())));
__ mov(ecx, Immediate(constant_elements));
FastCloneShallowArrayStub stub(
+ isolate(),
FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS,
allocation_site_mode,
length);
__ CallStub(&stub);
- } else if (expr->depth() > 1 || Serializer::enabled() ||
+ } else if (expr->depth() > 1 || Serializer::enabled(isolate()) ||
length > FastCloneShallowArrayStub::kMaximumClonedLength) {
__ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
__ push(FieldOperand(ebx, JSFunction::kLiteralsOffset));
@@ -1795,7 +1769,10 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
__ mov(eax, FieldOperand(ebx, JSFunction::kLiteralsOffset));
__ mov(ebx, Immediate(Smi::FromInt(expr->literal_index())));
__ mov(ecx, Immediate(constant_elements));
- FastCloneShallowArrayStub stub(mode, allocation_site_mode, length);
+ FastCloneShallowArrayStub stub(isolate(),
+ mode,
+ allocation_site_mode,
+ length);
__ CallStub(&stub);
}
@@ -1832,7 +1809,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
} else {
// Store the subexpression value in the array's elements.
__ mov(ecx, Immediate(Smi::FromInt(i)));
- StoreArrayLiteralElementStub stub;
+ StoreArrayLiteralElementStub stub(isolate());
__ CallStub(&stub);
}
@@ -1849,7 +1826,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
void FullCodeGenerator::VisitAssignment(Assignment* expr) {
- ASSERT(expr->target()->IsValidLeftHandSide());
+ ASSERT(expr->target()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ Assignment");
@@ -2081,7 +2058,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
CallIC(ic, TypeFeedbackId::None());
__ mov(edi, eax);
__ mov(Operand(esp, 2 * kPointerSize), edi);
- CallFunctionStub stub(1, CALL_AS_METHOD);
+ CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
__ CallStub(&stub);
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
@@ -2225,7 +2202,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
Label gc_required;
Label allocated;
- Handle<Map> map(isolate()->native_context()->generator_result_map());
+ Handle<Map> map(isolate()->native_context()->iterator_result_map());
__ Allocate(map->instance_size(), eax, ecx, edx, &gc_required, TAG_OBJECT);
__ jmp(&allocated);
@@ -2288,8 +2265,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ bind(&stub_call);
__ mov(eax, ecx);
- BinaryOpICStub stub(op, mode);
- CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
+ BinaryOpICStub stub(isolate(), op, mode);
+ CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done, Label::kNear);
@@ -2371,16 +2348,16 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode) {
__ pop(edx);
- BinaryOpICStub stub(op, mode);
+ BinaryOpICStub stub(isolate(), op, mode);
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
- CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
+ CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
context()->Plug(eax);
}
void FullCodeGenerator::EmitAssignment(Expression* expr) {
- ASSERT(expr->IsValidLeftHandSide());
+ ASSERT(expr->IsValidReferenceExpression());
// Left-hand side can only be a property, a global or a (parameter or local)
// slot.
@@ -2580,17 +2557,15 @@ void FullCodeGenerator::CallIC(Handle<Code> code,
}
-
-
// Code common for calls using the IC.
-void FullCodeGenerator::EmitCallWithIC(Call* expr) {
+void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
- ZoneList<Expression*>* args = expr->arguments();
- int arg_count = args->length();
- CallFunctionFlags flags;
+ CallIC::CallType call_type = callee->IsVariableProxy()
+ ? CallIC::FUNCTION
+ : CallIC::METHOD;
// Get the target function.
- if (callee->IsVariableProxy()) {
+ if (call_type == CallIC::FUNCTION) {
{ StackValueContext context(this);
EmitVariableLoad(callee->AsVariableProxy());
PrepareForBailout(callee, NO_REGISTERS);
@@ -2598,7 +2573,6 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr) {
// Push undefined as receiver. This is patched in the method prologue if it
// is a sloppy mode method.
__ push(Immediate(isolate()->factory()->undefined_value()));
- flags = NO_CALL_FUNCTION_FLAGS;
} else {
// Load the function from the receiver.
ASSERT(callee->IsProperty());
@@ -2608,39 +2582,19 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr) {
// Push the target function under the receiver.
__ push(Operand(esp, 0));
__ mov(Operand(esp, kPointerSize), eax);
- flags = CALL_AS_METHOD;
}
- // Load the arguments.
- { PreservePositionScope scope(masm()->positions_recorder());
- for (int i = 0; i < arg_count; i++) {
- VisitForStackValue(args->at(i));
- }
- }
-
- // Record source position of the IC call.
- SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, flags);
- __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
- __ CallStub(&stub);
- RecordJSReturnSite(expr);
-
- // Restore context register.
- __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
-
- context()->DropAndPlug(1, eax);
+ EmitCall(expr, call_type);
}
// Code common for calls using the IC.
-void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
- Expression* key) {
+void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
+ Expression* key) {
// Load the key.
VisitForAccumulatorValue(key);
Expression* callee = expr->expression();
- ZoneList<Expression*>* args = expr->arguments();
- int arg_count = args->length();
// Load the function from the receiver.
ASSERT(callee->IsProperty());
@@ -2654,29 +2608,12 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
__ push(Operand(esp, 0));
__ mov(Operand(esp, kPointerSize), eax);
- // Load the arguments.
- { PreservePositionScope scope(masm()->positions_recorder());
- for (int i = 0; i < arg_count; i++) {
- VisitForStackValue(args->at(i));
- }
- }
-
- // Record source position of the IC call.
- SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, CALL_AS_METHOD);
- __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
- __ CallStub(&stub);
- RecordJSReturnSite(expr);
-
- // Restore context register.
- __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
-
- context()->DropAndPlug(1, eax);
+ EmitCall(expr, CallIC::METHOD);
}
-void FullCodeGenerator::EmitCallWithStub(Call* expr) {
- // Code common for calls using the call stub.
+void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) {
+ // Load the arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope scope(masm()->positions_recorder());
@@ -2684,23 +2621,22 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr) {
VisitForStackValue(args->at(i));
}
}
- // Record source position for debugger.
- SetSourcePosition(expr->position());
- Handle<Object> uninitialized =
- TypeFeedbackInfo::UninitializedSentinel(isolate());
- StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
- __ LoadHeapObject(ebx, FeedbackVector());
- __ mov(edx, Immediate(Smi::FromInt(expr->CallFeedbackSlot())));
-
- // Record call targets in unoptimized code.
- CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
+ // Record source position of the IC call.
+ SetSourcePosition(expr->position());
+ Handle<Code> ic = CallIC::initialize_stub(
+ isolate(), arg_count, call_type);
+ __ Move(edx, Immediate(Smi::FromInt(expr->CallFeedbackSlot())));
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
- __ CallStub(&stub);
+ // Don't assign a type feedback id to the IC, since type feedback is provided
+ // by the vector above.
+ CallIC(ic);
RecordJSReturnSite(expr);
+
// Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
+
context()->DropAndPlug(1, eax);
}
@@ -2764,7 +2700,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
}
// Record source position for debugger.
SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
+ CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
RecordJSReturnSite(expr);
@@ -2773,7 +2709,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
context()->DropAndPlug(1, eax);
} else if (call_type == Call::GLOBAL_CALL) {
- EmitCallWithIC(expr);
+ EmitCallWithLoadIC(expr);
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
// Call to a lookup slot (dynamically introduced variable).
@@ -2809,7 +2745,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// The receiver is either the global receiver or an object found by
// LoadContextSlot.
- EmitCallWithStub(expr);
+ EmitCall(expr);
} else if (call_type == Call::PROPERTY_CALL) {
Property* property = callee->AsProperty();
@@ -2817,9 +2753,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
VisitForStackValue(property->obj());
}
if (property->key()->IsPropertyName()) {
- EmitCallWithIC(expr);
+ EmitCallWithLoadIC(expr);
} else {
- EmitKeyedCallWithIC(expr, property->key());
+ EmitKeyedCallWithLoadIC(expr, property->key());
}
} else {
@@ -2830,7 +2766,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
}
__ push(Immediate(isolate()->factory()->undefined_value()));
// Emit function call.
- EmitCallWithStub(expr);
+ EmitCall(expr);
}
#ifdef DEBUG
@@ -2867,12 +2803,8 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
__ mov(edi, Operand(esp, arg_count * kPointerSize));
// Record call targets in unoptimized code.
- Handle<Object> uninitialized =
- TypeFeedbackInfo::UninitializedSentinel(isolate());
- StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
if (FLAG_pretenuring_call_new) {
- StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(),
- isolate()->factory()->NewAllocationSite());
+ EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
ASSERT(expr->AllocationSiteFeedbackSlot() ==
expr->CallNewFeedbackSlot() + 1);
}
@@ -2880,8 +2812,8 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
__ LoadHeapObject(ebx, FeedbackVector());
__ mov(edx, Immediate(Smi::FromInt(expr->CallNewFeedbackSlot())));
- CallConstructStub stub(RECORD_CALL_TARGET);
- __ call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
+ CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
+ __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
context()->Plug(eax);
}
@@ -3257,7 +3189,7 @@ void FullCodeGenerator::EmitArguments(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(0));
__ mov(edx, eax);
__ Move(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters())));
- ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
+ ArgumentsAccessStub stub(isolate(), ArgumentsAccessStub::READ_ELEMENT);
__ CallStub(&stub);
context()->Plug(eax);
}
@@ -3347,30 +3279,9 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
}
-void FullCodeGenerator::EmitLog(CallRuntime* expr) {
- // Conditionally generate a log call.
- // Args:
- // 0 (literal string): The type of logging (corresponds to the flags).
- // This is used to determine whether or not to generate the log call.
- // 1 (string): Format string. Access the string at argument index 2
- // with '%2s' (see Logger::LogRuntime for all the formats).
- // 2 (array): Arguments to the format string.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT_EQ(args->length(), 3);
- if (CodeGenerator::ShouldGenerateLog(isolate(), args->at(0))) {
- VisitForStackValue(args->at(1));
- VisitForStackValue(args->at(2));
- __ CallRuntime(Runtime::kHiddenLog, 2);
- }
- // Finally, we're expected to leave a value on the top of the stack.
- __ mov(eax, isolate()->factory()->undefined_value());
- context()->Plug(eax);
-}
-
-
void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
// Load the arguments on the stack and call the stub.
- SubStringStub stub;
+ SubStringStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 3);
VisitForStackValue(args->at(0));
@@ -3383,7 +3294,7 @@ void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) {
// Load the arguments on the stack and call the stub.
- RegExpExecStub stub;
+ RegExpExecStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 4);
VisitForStackValue(args->at(0));
@@ -3536,10 +3447,10 @@ void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
VisitForStackValue(args->at(1));
if (CpuFeatures::IsSupported(SSE2)) {
- MathPowStub stub(MathPowStub::ON_STACK);
+ MathPowStub stub(isolate(), MathPowStub::ON_STACK);
__ CallStub(&stub);
} else {
- __ CallRuntime(Runtime::kMath_pow, 2);
+ __ CallRuntime(Runtime::kHiddenMathPowSlow, 2);
}
context()->Plug(eax);
}
@@ -3581,7 +3492,7 @@ void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
// Load the argument into eax and call the stub.
VisitForAccumulatorValue(args->at(0));
- NumberToStringStub stub;
+ NumberToStringStub stub(isolate());
__ CallStub(&stub);
context()->Plug(eax);
}
@@ -3707,7 +3618,7 @@ void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(1));
__ pop(edx);
- StringAddStub stub(STRING_ADD_CHECK_BOTH, NOT_TENURED);
+ StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED);
__ CallStub(&stub);
context()->Plug(eax);
}
@@ -3720,32 +3631,12 @@ void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
- StringCompareStub stub;
+ StringCompareStub stub(isolate());
__ CallStub(&stub);
context()->Plug(eax);
}
-void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_log, 1);
- context()->Plug(eax);
-}
-
-
-void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_sqrt, 1);
- context()->Plug(eax);
-}
-
-
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() >= 2);
@@ -3780,7 +3671,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
// Load the arguments on the stack and call the stub.
- RegExpConstructResultStub stub;
+ RegExpConstructResultStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 3);
VisitForStackValue(args->at(0));
@@ -4178,7 +4069,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
// Record source position of the IC call.
SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
+ CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
// Restore context register.
@@ -4315,7 +4206,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
- ASSERT(expr->expression()->IsValidLeftHandSide());
+ ASSERT(expr->expression()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ CountOperation");
SetSourcePosition(expr->position());
@@ -4407,7 +4298,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ jmp(&stub_call, Label::kNear);
__ bind(&slow);
}
- ToNumberStub convert_stub;
+ ToNumberStub convert_stub(isolate());
__ CallStub(&convert_stub);
// Save result for postfix expressions.
@@ -4437,8 +4328,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ bind(&stub_call);
__ mov(edx, eax);
__ mov(eax, Immediate(Smi::FromInt(1)));
- BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE);
- CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId());
+ BinaryOpICStub stub(isolate(), expr->binary_op(), NO_OVERWRITE);
+ CallIC(stub.GetCode(), expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
@@ -4554,12 +4445,13 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
}
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
- if (check->Equals(isolate()->heap()->number_string())) {
+ Factory* factory = isolate()->factory();
+ if (String::Equals(check, factory->number_string())) {
__ JumpIfSmi(eax, if_true);
__ cmp(FieldOperand(eax, HeapObject::kMapOffset),
isolate()->factory()->heap_number_map());
Split(equal, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->string_string())) {
+ } else if (String::Equals(check, factory->string_string())) {
__ JumpIfSmi(eax, if_false);
__ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edx);
__ j(above_equal, if_false);
@@ -4567,20 +4459,20 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ test_b(FieldOperand(edx, Map::kBitFieldOffset),
1 << Map::kIsUndetectable);
Split(zero, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->symbol_string())) {
+ } else if (String::Equals(check, factory->symbol_string())) {
__ JumpIfSmi(eax, if_false);
__ CmpObjectType(eax, SYMBOL_TYPE, edx);
Split(equal, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->boolean_string())) {
+ } else if (String::Equals(check, factory->boolean_string())) {
__ cmp(eax, isolate()->factory()->true_value());
__ j(equal, if_true);
__ cmp(eax, isolate()->factory()->false_value());
Split(equal, if_true, if_false, fall_through);
} else if (FLAG_harmony_typeof &&
- check->Equals(isolate()->heap()->null_string())) {
+ String::Equals(check, factory->null_string())) {
__ cmp(eax, isolate()->factory()->null_value());
Split(equal, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->undefined_string())) {
+ } else if (String::Equals(check, factory->undefined_string())) {
__ cmp(eax, isolate()->factory()->undefined_value());
__ j(equal, if_true);
__ JumpIfSmi(eax, if_false);
@@ -4589,14 +4481,14 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset));
__ test(ecx, Immediate(1 << Map::kIsUndetectable));
Split(not_zero, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->function_string())) {
+ } else if (String::Equals(check, factory->function_string())) {
__ JumpIfSmi(eax, if_false);
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
__ CmpObjectType(eax, JS_FUNCTION_TYPE, edx);
__ j(equal, if_true);
__ CmpInstanceType(edx, JS_FUNCTION_PROXY_TYPE);
Split(equal, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->object_string())) {
+ } else if (String::Equals(check, factory->object_string())) {
__ JumpIfSmi(eax, if_false);
if (!FLAG_harmony_typeof) {
__ cmp(eax, isolate()->factory()->null_value());
@@ -4647,7 +4539,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
case Token::INSTANCEOF: {
VisitForStackValue(expr->right());
- InstanceofStub stub(InstanceofStub::kNoFlags);
+ InstanceofStub stub(isolate(), InstanceofStub::kNoFlags);
__ CallStub(&stub);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
__ test(eax, eax);
diff --git a/deps/v8/src/ia32/ic-ia32.cc b/deps/v8/src/ia32/ic-ia32.cc
index c2be7da1a4..52aa0ea110 100644
--- a/deps/v8/src/ia32/ic-ia32.cc
+++ b/deps/v8/src/ia32/ic-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -1282,7 +1259,7 @@ void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) {
Address delta_address = test_instruction_address + 1;
// The delta to the start of the map check instruction and the
// condition code uses at the patched jump.
- int8_t delta = *reinterpret_cast<int8_t*>(delta_address);
+ uint8_t delta = *reinterpret_cast<uint8_t*>(delta_address);
if (FLAG_trace_ic) {
PrintF("[ patching ic at %p, test=%p, delta=%d\n",
address, test_instruction_address, delta);
diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.cc b/deps/v8/src/ia32/lithium-codegen-ia32.cc
index 0dbe3da13d..2872d4dc0d 100644
--- a/deps/v8/src/ia32/lithium-codegen-ia32.cc
+++ b/deps/v8/src/ia32/lithium-codegen-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -41,9 +18,10 @@ namespace v8 {
namespace internal {
-static SaveFPRegsMode GetSaveFPRegsMode() {
+static SaveFPRegsMode GetSaveFPRegsMode(Isolate* isolate) {
// We don't need to save floating point regs when generating the snapshot
- return CpuFeatures::IsSafeForSnapshot(SSE2) ? kSaveFPRegs : kDontSaveFPRegs;
+ return CpuFeatures::IsSafeForSnapshot(isolate, SSE2) ? kSaveFPRegs
+ : kDontSaveFPRegs;
}
@@ -108,13 +86,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
if (!info()->IsStub()) {
Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
}
- info()->CommitDependencies(code);
-}
-
-
-void LCodeGen::Abort(BailoutReason reason) {
- info()->set_bailout_reason(reason);
- status_ = ABORTED;
}
@@ -293,7 +264,7 @@ bool LCodeGen::GeneratePrologue() {
Comment(";;; Allocate local context");
// Argument to NewContext is the function, which is still in edi.
if (heap_slots <= FastNewContextStub::kMaximumSlots) {
- FastNewContextStub stub(heap_slots);
+ FastNewContextStub stub(isolate(), heap_slots);
__ CallStub(&stub);
} else {
__ push(edi);
@@ -406,7 +377,7 @@ void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) {
x87_stack_.LeavingBlock(current_block_, LGoto::cast(instr));
} else if (FLAG_debug_code && FLAG_enable_slow_asserts &&
!instr->IsGap() && !instr->IsReturn()) {
- if (instr->ClobbersDoubleRegisters()) {
+ if (instr->ClobbersDoubleRegisters(isolate())) {
if (instr->HasDoubleRegisterResult()) {
ASSERT_EQ(1, x87_stack_.depth());
} else {
@@ -705,7 +676,7 @@ void LCodeGen::X87PrepareBinaryOp(
void LCodeGen::X87Stack::FlushIfNecessary(LInstruction* instr, LCodeGen* cgen) {
- if (stack_depth_ > 0 && instr->ClobbersDoubleRegisters()) {
+ if (stack_depth_ > 0 && instr->ClobbersDoubleRegisters(isolate())) {
bool double_inputs = instr->HasDoubleRegisterInput();
// Flush stack from tos down, since FreeX87() will mess with tos
@@ -1051,6 +1022,7 @@ void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
void LCodeGen::RegisterEnvironmentForDeoptimization(
LEnvironment* environment, Safepoint::DeoptMode mode) {
+ environment->set_has_been_used();
if (!environment->HasBeenRegistered()) {
// Physical stack frame layout:
// -x ............. -4 0 ..................................... y
@@ -1175,7 +1147,7 @@ void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
int length = deoptimizations_.length();
if (length == 0) return;
Handle<DeoptimizationInputData> data =
- factory()->NewDeoptimizationInputData(length, TENURED);
+ DeoptimizationInputData::New(isolate(), length, TENURED);
Handle<ByteArray> translations =
translations_.CreateByteArray(isolate()->factory());
@@ -1349,18 +1321,18 @@ void LCodeGen::DoCallStub(LCallStub* instr) {
ASSERT(ToRegister(instr->result()).is(eax));
switch (instr->hydrogen()->major_key()) {
case CodeStub::RegExpExec: {
- RegExpExecStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ RegExpExecStub stub(isolate());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
case CodeStub::SubString: {
- SubStringStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ SubStringStub stub(isolate());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
case CodeStub::StringCompare: {
- StringCompareStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ StringCompareStub stub(isolate());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
default:
@@ -1493,7 +1465,7 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
Register dividend = ToRegister(instr->dividend());
int32_t divisor = instr->divisor();
Register result = ToRegister(instr->result());
- ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor))));
+ ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor)));
ASSERT(!result.is(dividend));
// Check for (0 / -x) that will produce negative zero.
@@ -1556,15 +1528,15 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
}
+// TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI.
void LCodeGen::DoDivI(LDivI* instr) {
HBinaryOperation* hdiv = instr->hydrogen();
- Register dividend = ToRegister(instr->left());
- Register divisor = ToRegister(instr->right());
+ Register dividend = ToRegister(instr->dividend());
+ Register divisor = ToRegister(instr->divisor());
Register remainder = ToRegister(instr->temp());
- Register result = ToRegister(instr->result());
ASSERT(dividend.is(eax));
ASSERT(remainder.is(edx));
- ASSERT(result.is(eax));
+ ASSERT(ToRegister(instr->result()).is(eax));
ASSERT(!divisor.is(eax));
ASSERT(!divisor.is(edx));
@@ -1598,15 +1570,7 @@ void LCodeGen::DoDivI(LDivI* instr) {
__ cdq();
__ idiv(divisor);
- if (hdiv->IsMathFloorOfDiv()) {
- Label done;
- __ test(remainder, remainder);
- __ j(zero, &done, Label::kNear);
- __ xor_(remainder, divisor);
- __ sar(remainder, 31);
- __ add(result, remainder);
- __ bind(&done);
- } else if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
+ if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
// Deoptimize if remainder is not 0.
__ test(remainder, remainder);
DeoptimizeIf(not_zero, instr->environment());
@@ -1629,22 +1593,26 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
}
// If the divisor is negative, we have to negate and handle edge cases.
- Label not_kmin_int, done;
__ neg(dividend);
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
DeoptimizeIf(zero, instr->environment());
}
- if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
- // Note that we could emit branch-free code, but that would need one more
- // register.
- if (divisor == -1) {
- DeoptimizeIf(overflow, instr->environment());
- } else {
- __ j(no_overflow, &not_kmin_int, Label::kNear);
- __ mov(dividend, Immediate(kMinInt / divisor));
- __ jmp(&done, Label::kNear);
- }
+
+ if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
+ __ sar(dividend, shift);
+ return;
+ }
+
+ // Dividing by -1 is basically negation, unless we overflow.
+ if (divisor == -1) {
+ DeoptimizeIf(overflow, instr->environment());
+ return;
}
+
+ Label not_kmin_int, done;
+ __ j(no_overflow, &not_kmin_int, Label::kNear);
+ __ mov(dividend, Immediate(kMinInt / divisor));
+ __ jmp(&done, Label::kNear);
__ bind(&not_kmin_int);
__ sar(dividend, shift);
__ bind(&done);
@@ -1696,6 +1664,59 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
}
+// TODO(svenpanne) Refactor this to avoid code duplication with DoDivI.
+void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
+ HBinaryOperation* hdiv = instr->hydrogen();
+ Register dividend = ToRegister(instr->dividend());
+ Register divisor = ToRegister(instr->divisor());
+ Register remainder = ToRegister(instr->temp());
+ Register result = ToRegister(instr->result());
+ ASSERT(dividend.is(eax));
+ ASSERT(remainder.is(edx));
+ ASSERT(result.is(eax));
+ ASSERT(!divisor.is(eax));
+ ASSERT(!divisor.is(edx));
+
+ // Check for x / 0.
+ if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
+ __ test(divisor, divisor);
+ DeoptimizeIf(zero, instr->environment());
+ }
+
+ // Check for (0 / -x) that will produce negative zero.
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ Label dividend_not_zero;
+ __ test(dividend, dividend);
+ __ j(not_zero, &dividend_not_zero, Label::kNear);
+ __ test(divisor, divisor);
+ DeoptimizeIf(sign, instr->environment());
+ __ bind(&dividend_not_zero);
+ }
+
+ // Check for (kMinInt / -1).
+ if (hdiv->CheckFlag(HValue::kCanOverflow)) {
+ Label dividend_not_min_int;
+ __ cmp(dividend, kMinInt);
+ __ j(not_zero, &dividend_not_min_int, Label::kNear);
+ __ cmp(divisor, -1);
+ DeoptimizeIf(zero, instr->environment());
+ __ bind(&dividend_not_min_int);
+ }
+
+ // Sign extend to edx (= remainder).
+ __ cdq();
+ __ idiv(divisor);
+
+ Label done;
+ __ test(remainder, remainder);
+ __ j(zero, &done, Label::kNear);
+ __ xor_(remainder, divisor);
+ __ sar(remainder, 31);
+ __ add(result, remainder);
+ __ bind(&done);
+}
+
+
void LCodeGen::DoMulI(LMulI* instr) {
Register left = ToRegister(instr->left());
LOperand* right = instr->right();
@@ -1942,7 +1963,7 @@ void LCodeGen::DoConstantD(LConstantD* instr) {
int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt));
ASSERT(instr->result()->IsDoubleRegister());
- if (!CpuFeatures::IsSafeForSnapshot(SSE2)) {
+ if (!CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) {
__ push(Immediate(upper));
__ push(Immediate(lower));
X87Register reg = ToX87Register(instr->result());
@@ -1990,9 +2011,16 @@ void LCodeGen::DoConstantE(LConstantE* instr) {
void LCodeGen::DoConstantT(LConstantT* instr) {
Register reg = ToRegister(instr->result());
- Handle<Object> handle = instr->value(isolate());
+ Handle<Object> object = instr->value(isolate());
AllowDeferredHandleDereference smi_check;
- __ LoadObject(reg, handle);
+ if (instr->hydrogen()->HasObjectMap()) {
+ Handle<Map> object_map = instr->hydrogen()->ObjectMap().handle();
+ ASSERT(object->IsHeapObject());
+ ASSERT(!object_map->is_stable() ||
+ *object_map == Handle<HeapObject>::cast(object)->map());
+ USE(object_map);
+ }
+ __ LoadObject(reg, object);
}
@@ -2215,7 +2243,7 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
- if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
+ if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) {
CpuFeatureScope scope(masm(), SSE2);
XMMRegister left = ToDoubleRegister(instr->left());
XMMRegister right = ToDoubleRegister(instr->right());
@@ -2307,8 +2335,8 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
ASSERT(ToRegister(instr->right()).is(eax));
ASSERT(ToRegister(instr->result()).is(eax));
- BinaryOpICStub stub(instr->op(), NO_OVERWRITE);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
@@ -2460,7 +2488,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
__ cmp(FieldOperand(reg, HeapObject::kMapOffset),
factory()->heap_number_map());
__ j(not_equal, &not_heap_number, Label::kNear);
- if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
+ if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) {
CpuFeatureScope scope(masm(), SSE2);
XMMRegister xmm_scratch = double_scratch0();
__ xorps(xmm_scratch, xmm_scratch);
@@ -2547,7 +2575,7 @@ void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
EmitGoto(next_block);
} else {
if (instr->is_double()) {
- if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
+ if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) {
CpuFeatureScope scope(masm(), SSE2);
__ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
} else {
@@ -2925,8 +2953,8 @@ void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
// Object and function are in fixed registers defined by the stub.
ASSERT(ToRegister(instr->context()).is(esi));
- InstanceofStub stub(InstanceofStub::kArgsInRegisters);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
Label true_value, done;
__ test(eax, Operand(eax));
@@ -3014,7 +3042,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
flags | InstanceofStub::kCallSiteInlineCheck);
flags = static_cast<InstanceofStub::Flags>(
flags | InstanceofStub::kReturnTrueFalseObject);
- InstanceofStub stub(flags);
+ InstanceofStub stub(isolate(), flags);
// Get the temp register reserved by the instruction. This needs to be a
// register which is pushed last by PushSafepointRegisters as top of the
@@ -3027,7 +3055,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
__ mov(temp, Immediate(delta));
__ StoreToSafepointRegisterSlot(temp, temp);
- CallCodeGeneric(stub.GetCode(isolate()),
+ CallCodeGeneric(stub.GetCode(),
RelocInfo::CODE_TARGET,
instr,
RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
@@ -3223,7 +3251,7 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
offset,
value,
temp,
- GetSaveFPRegsMode(),
+ GetSaveFPRegsMode(isolate()),
EMIT_REMEMBERED_SET,
check_needed);
}
@@ -4117,7 +4145,7 @@ void LCodeGen::DoPower(LPower* instr) {
ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
if (exponent_type.IsSmi()) {
- MathPowStub stub(MathPowStub::TAGGED);
+ MathPowStub stub(isolate(), MathPowStub::TAGGED);
__ CallStub(&stub);
} else if (exponent_type.IsTagged()) {
Label no_deopt;
@@ -4125,14 +4153,14 @@ void LCodeGen::DoPower(LPower* instr) {
__ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx);
DeoptimizeIf(not_equal, instr->environment());
__ bind(&no_deopt);
- MathPowStub stub(MathPowStub::TAGGED);
+ MathPowStub stub(isolate(), MathPowStub::TAGGED);
__ CallStub(&stub);
} else if (exponent_type.IsInteger32()) {
- MathPowStub stub(MathPowStub::INTEGER);
+ MathPowStub stub(isolate(), MathPowStub::INTEGER);
__ CallStub(&stub);
} else {
ASSERT(exponent_type.IsDouble());
- MathPowStub stub(MathPowStub::DOUBLE);
+ MathPowStub stub(isolate(), MathPowStub::DOUBLE);
__ CallStub(&stub);
}
}
@@ -4225,8 +4253,8 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
ASSERT(ToRegister(instr->result()).is(eax));
int arity = instr->arity();
- CallFunctionStub stub(arity, instr->hydrogen()->function_flags());
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
@@ -4237,9 +4265,9 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
// No cell in ebx for construct type feedback in optimized code
__ mov(ebx, isolate()->factory()->undefined_value());
- CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
+ CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ Move(eax, Immediate(instr->arity()));
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
}
@@ -4257,8 +4285,8 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
: DONT_OVERRIDE;
if (instr->arity() == 0) {
- ArrayNoArgumentConstructorStub stub(kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
} else if (instr->arity() == 1) {
Label done;
if (IsFastPackedElementsKind(kind)) {
@@ -4270,18 +4298,20 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
__ j(zero, &packed_case, Label::kNear);
ElementsKind holey_kind = GetHoleyElementsKind(kind);
- ArraySingleArgumentConstructorStub stub(holey_kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArraySingleArgumentConstructorStub stub(isolate(),
+ holey_kind,
+ override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
__ jmp(&done, Label::kNear);
__ bind(&packed_case);
}
- ArraySingleArgumentConstructorStub stub(kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
__ bind(&done);
} else {
- ArrayNArgumentsConstructorStub stub(kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
}
}
@@ -4314,7 +4344,7 @@ void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
- Representation representation = instr->representation();
+ Representation representation = instr->hydrogen()->field_representation();
HObjectAccess access = instr->hydrogen()->access();
int offset = access.offset();
@@ -4336,7 +4366,6 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
}
Register object = ToRegister(instr->object());
- Handle<Map> transition = instr->transition();
SmiCheck check_needed =
instr->hydrogen()->value()->IsHeapObject()
? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
@@ -4356,13 +4385,13 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
__ test(value, Immediate(kSmiTagMask));
DeoptimizeIf(zero, instr->environment());
- // We know that value is a smi now, so we can omit the check below.
+ // We know now that value is not a smi, so we can omit the check below.
check_needed = OMIT_SMI_CHECK;
}
}
} else if (representation.IsDouble()) {
- ASSERT(transition.is_null());
ASSERT(access.IsInobject());
+ ASSERT(!instr->hydrogen()->has_transition());
ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
if (CpuFeatures::IsSupported(SSE2)) {
CpuFeatureScope scope(masm(), SSE2);
@@ -4375,7 +4404,9 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
return;
}
- if (!transition.is_null()) {
+ if (instr->hydrogen()->has_transition()) {
+ Handle<Map> transition = instr->hydrogen()->transition_map();
+ AddDeprecationDependency(transition);
if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
__ mov(FieldOperand(object, HeapObject::kMapOffset), transition);
} else {
@@ -4388,7 +4419,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
HeapObject::kMapOffset,
temp_map,
temp,
- GetSaveFPRegsMode(),
+ GetSaveFPRegsMode(isolate()),
OMIT_REMEMBERED_SET,
OMIT_SMI_CHECK);
}
@@ -4429,7 +4460,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
offset,
value,
temp,
- GetSaveFPRegsMode(),
+ GetSaveFPRegsMode(isolate()),
EMIT_REMEMBERED_SET,
check_needed);
}
@@ -4447,34 +4478,27 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
}
-void LCodeGen::ApplyCheckIf(Condition cc, LBoundsCheck* check) {
- if (FLAG_debug_code && check->hydrogen()->skip_check()) {
+void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
+ Condition cc = instr->hydrogen()->allow_equality() ? above : above_equal;
+ if (instr->index()->IsConstantOperand()) {
+ __ cmp(ToOperand(instr->length()),
+ ToImmediate(LConstantOperand::cast(instr->index()),
+ instr->hydrogen()->length()->representation()));
+ cc = ReverseCondition(cc);
+ } else if (instr->length()->IsConstantOperand()) {
+ __ cmp(ToOperand(instr->index()),
+ ToImmediate(LConstantOperand::cast(instr->length()),
+ instr->hydrogen()->index()->representation()));
+ } else {
+ __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
+ }
+ if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
Label done;
__ j(NegateCondition(cc), &done, Label::kNear);
__ int3();
__ bind(&done);
} else {
- DeoptimizeIf(cc, check->environment());
- }
-}
-
-
-void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
- if (instr->hydrogen()->skip_check() && !FLAG_debug_code) return;
-
- if (instr->index()->IsConstantOperand()) {
- Immediate immediate =
- ToImmediate(LConstantOperand::cast(instr->index()),
- instr->hydrogen()->length()->representation());
- __ cmp(ToOperand(instr->length()), immediate);
- Condition condition =
- instr->hydrogen()->allow_equality() ? below : below_equal;
- ApplyCheckIf(condition, instr);
- } else {
- __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
- Condition condition =
- instr->hydrogen()->allow_equality() ? above : above_equal;
- ApplyCheckIf(condition, instr);
+ DeoptimizeIf(cc, instr->environment());
}
}
@@ -4496,7 +4520,7 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
instr->additional_index()));
if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
elements_kind == FLOAT32_ELEMENTS) {
- if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
+ if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) {
CpuFeatureScope scope(masm(), SSE2);
XMMRegister xmm_scratch = double_scratch0();
__ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value()));
@@ -4507,7 +4531,7 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
}
} else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
elements_kind == FLOAT64_ELEMENTS) {
- if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
+ if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) {
CpuFeatureScope scope(masm(), SSE2);
__ movsd(operand, ToDoubleRegister(instr->value()));
} else {
@@ -4566,7 +4590,7 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
FixedDoubleArray::kHeaderSize - kHeapObjectTag,
instr->additional_index());
- if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
+ if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) {
CpuFeatureScope scope(masm(), SSE2);
XMMRegister value = ToDoubleRegister(instr->value());
@@ -4668,7 +4692,7 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
__ RecordWrite(elements,
key,
value,
- GetSaveFPRegsMode(),
+ GetSaveFPRegsMode(isolate()),
EMIT_REMEMBERED_SET,
check_needed);
}
@@ -4736,16 +4760,14 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
kDontSaveFPRegs);
} else {
ASSERT(ToRegister(instr->context()).is(esi));
+ ASSERT(object_reg.is(eax));
PushSafepointRegistersScope scope(this);
- if (!object_reg.is(eax)) {
- __ mov(eax, object_reg);
- }
__ mov(ebx, to_map);
bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
- TransitionElementsKindStub stub(from_kind, to_kind, is_js_array);
+ TransitionElementsKindStub stub(isolate(), from_kind, to_kind, is_js_array);
__ CallStub(&stub);
- RecordSafepointWithRegisters(
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
+ RecordSafepointWithLazyDeopt(instr,
+ RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
}
__ bind(&not_applicable);
}
@@ -4866,9 +4888,10 @@ void LCodeGen::DoStringAdd(LStringAdd* instr) {
ASSERT(ToRegister(instr->context()).is(esi));
ASSERT(ToRegister(instr->left()).is(edx));
ASSERT(ToRegister(instr->right()).is(eax));
- StringAddStub stub(instr->hydrogen()->flags(),
+ StringAddStub stub(isolate(),
+ instr->hydrogen()->flags(),
instr->hydrogen()->pretenure_flag());
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
@@ -5406,7 +5429,7 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
Register result_reg = ToRegister(result);
if (instr->truncating()) {
- if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
+ if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) {
CpuFeatureScope scope(masm(), SSE2);
XMMRegister input_reg = ToDoubleRegister(input);
__ TruncateDoubleToI(result_reg, input_reg);
@@ -5417,7 +5440,7 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
}
} else {
Label bailout, done;
- if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
+ if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) {
CpuFeatureScope scope(masm(), SSE2);
XMMRegister input_reg = ToDoubleRegister(input);
XMMRegister xmm_scratch = double_scratch0();
@@ -5445,7 +5468,7 @@ void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
Register result_reg = ToRegister(result);
Label bailout, done;
- if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
+ if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) {
CpuFeatureScope scope(masm(), SSE2);
XMMRegister input_reg = ToDoubleRegister(input);
XMMRegister xmm_scratch = double_scratch0();
@@ -5578,29 +5601,35 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
Register object_;
};
- if (instr->hydrogen()->CanOmitMapChecks()) return;
+ if (instr->hydrogen()->IsStabilityCheck()) {
+ const UniqueSet<Map>* maps = instr->hydrogen()->maps();
+ for (int i = 0; i < maps->size(); ++i) {
+ AddStabilityDependency(maps->at(i).handle());
+ }
+ return;
+ }
LOperand* input = instr->value();
ASSERT(input->IsRegister());
Register reg = ToRegister(input);
DeferredCheckMaps* deferred = NULL;
- if (instr->hydrogen()->has_migration_target()) {
+ if (instr->hydrogen()->HasMigrationTarget()) {
deferred = new(zone()) DeferredCheckMaps(this, instr, reg, x87_stack_);
__ bind(deferred->check_maps());
}
- UniqueSet<Map> map_set = instr->hydrogen()->map_set();
+ const UniqueSet<Map>* maps = instr->hydrogen()->maps();
Label success;
- for (int i = 0; i < map_set.size() - 1; i++) {
- Handle<Map> map = map_set.at(i).handle();
+ for (int i = 0; i < maps->size() - 1; i++) {
+ Handle<Map> map = maps->at(i).handle();
__ CompareMap(reg, map);
__ j(equal, &success, Label::kNear);
}
- Handle<Map> map = map_set.at(map_set.size() - 1).handle();
+ Handle<Map> map = maps->at(maps->size() - 1).handle();
__ CompareMap(reg, map);
- if (instr->hydrogen()->has_migration_target()) {
+ if (instr->hydrogen()->HasMigrationTarget()) {
__ j(not_equal, deferred->entry());
} else {
DeoptimizeIf(not_equal, instr->environment());
@@ -5908,7 +5937,13 @@ void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
__ push(size);
} else {
int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
- __ push(Immediate(Smi::FromInt(size)));
+ if (size >= 0 && size <= Smi::kMaxValue) {
+ __ push(Immediate(Smi::FromInt(size)));
+ } else {
+ // We should never get here at runtime => abort
+ __ int3();
+ return;
+ }
}
int flags = AllocateDoubleAlignFlag::encode(
@@ -5996,10 +6031,11 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
// space for nested functions that don't need literals cloning.
bool pretenure = instr->hydrogen()->pretenure();
if (!pretenure && instr->hydrogen()->has_no_literals()) {
- FastNewClosureStub stub(instr->hydrogen()->strict_mode(),
+ FastNewClosureStub stub(isolate(),
+ instr->hydrogen()->strict_mode(),
instr->hydrogen()->is_generator());
__ mov(ebx, Immediate(instr->hydrogen()->shared_info()));
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
} else {
__ push(esi);
__ push(Immediate(instr->hydrogen()->shared_info()));
@@ -6040,13 +6076,13 @@ Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
Label::Distance false_distance = right_block == next_block ? Label::kNear
: Label::kFar;
Condition final_branch_condition = no_condition;
- if (type_name->Equals(heap()->number_string())) {
+ if (String::Equals(type_name, factory()->number_string())) {
__ JumpIfSmi(input, true_label, true_distance);
__ cmp(FieldOperand(input, HeapObject::kMapOffset),
factory()->heap_number_map());
final_branch_condition = equal;
- } else if (type_name->Equals(heap()->string_string())) {
+ } else if (String::Equals(type_name, factory()->string_string())) {
__ JumpIfSmi(input, false_label, false_distance);
__ CmpObjectType(input, FIRST_NONSTRING_TYPE, input);
__ j(above_equal, false_label, false_distance);
@@ -6054,22 +6090,23 @@ Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
1 << Map::kIsUndetectable);
final_branch_condition = zero;
- } else if (type_name->Equals(heap()->symbol_string())) {
+ } else if (String::Equals(type_name, factory()->symbol_string())) {
__ JumpIfSmi(input, false_label, false_distance);
__ CmpObjectType(input, SYMBOL_TYPE, input);
final_branch_condition = equal;
- } else if (type_name->Equals(heap()->boolean_string())) {
+ } else if (String::Equals(type_name, factory()->boolean_string())) {
__ cmp(input, factory()->true_value());
__ j(equal, true_label, true_distance);
__ cmp(input, factory()->false_value());
final_branch_condition = equal;
- } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) {
+ } else if (FLAG_harmony_typeof &&
+ String::Equals(type_name, factory()->null_string())) {
__ cmp(input, factory()->null_value());
final_branch_condition = equal;
- } else if (type_name->Equals(heap()->undefined_string())) {
+ } else if (String::Equals(type_name, factory()->undefined_string())) {
__ cmp(input, factory()->undefined_value());
__ j(equal, true_label, true_distance);
__ JumpIfSmi(input, false_label, false_distance);
@@ -6079,7 +6116,7 @@ Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
1 << Map::kIsUndetectable);
final_branch_condition = not_zero;
- } else if (type_name->Equals(heap()->function_string())) {
+ } else if (String::Equals(type_name, factory()->function_string())) {
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
__ JumpIfSmi(input, false_label, false_distance);
__ CmpObjectType(input, JS_FUNCTION_TYPE, input);
@@ -6087,7 +6124,7 @@ Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
__ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE);
final_branch_condition = equal;
- } else if (type_name->Equals(heap()->object_string())) {
+ } else if (String::Equals(type_name, factory()->object_string())) {
__ JumpIfSmi(input, false_label, false_distance);
if (!FLAG_harmony_typeof) {
__ cmp(input, factory()->null_value());
@@ -6325,11 +6362,56 @@ void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
}
+void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
+ Register object,
+ Register index) {
+ PushSafepointRegistersScope scope(this);
+ __ push(object);
+ __ push(index);
+ __ xor_(esi, esi);
+ __ CallRuntimeSaveDoubles(Runtime::kLoadMutableDouble);
+ RecordSafepointWithRegisters(
+ instr->pointer_map(), 2, Safepoint::kNoLazyDeopt);
+ __ StoreToSafepointRegisterSlot(object, eax);
+}
+
+
void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
+ class DeferredLoadMutableDouble V8_FINAL : public LDeferredCode {
+ public:
+ DeferredLoadMutableDouble(LCodeGen* codegen,
+ LLoadFieldByIndex* instr,
+ Register object,
+ Register index,
+ const X87Stack& x87_stack)
+ : LDeferredCode(codegen, x87_stack),
+ instr_(instr),
+ object_(object),
+ index_(index) {
+ }
+ virtual void Generate() V8_OVERRIDE {
+ codegen()->DoDeferredLoadMutableDouble(instr_, object_, index_);
+ }
+ virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
+ private:
+ LLoadFieldByIndex* instr_;
+ Register object_;
+ Register index_;
+ };
+
Register object = ToRegister(instr->object());
Register index = ToRegister(instr->index());
+ DeferredLoadMutableDouble* deferred;
+ deferred = new(zone()) DeferredLoadMutableDouble(
+ this, instr, object, index, x87_stack_);
+
Label out_of_object, done;
+ __ test(index, Immediate(Smi::FromInt(1)));
+ __ j(not_zero, deferred->entry());
+
+ __ sar(index, 1);
+
__ cmp(index, Immediate(0));
__ j(less, &out_of_object, Label::kNear);
__ mov(object, FieldOperand(object,
@@ -6346,6 +6428,7 @@ void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
index,
times_half_pointer_size,
FixedArray::kHeaderSize - kPointerSize));
+ __ bind(deferred->exit());
__ bind(&done);
}
diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.h b/deps/v8/src/ia32/lithium-codegen-ia32.h
index 079595cba5..f4542eecdd 100644
--- a/deps/v8/src/ia32/lithium-codegen-ia32.h
+++ b/deps/v8/src/ia32/lithium-codegen-ia32.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_IA32_LITHIUM_CODEGEN_IA32_H_
#define V8_IA32_LITHIUM_CODEGEN_IA32_H_
@@ -36,7 +13,7 @@
#include "lithium-codegen.h"
#include "safepoint-table.h"
#include "scopes.h"
-#include "v8utils.h"
+#include "utils.h"
namespace v8 {
namespace internal {
@@ -163,6 +140,9 @@ class LCodeGen: public LCodeGenBase {
void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
Label* map_check);
void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
+ void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
+ Register object,
+ Register index);
// Parallel move support.
void DoParallelMove(LParallelMove* move);
@@ -194,8 +174,6 @@ class LCodeGen: public LCodeGenBase {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
- void Abort(BailoutReason reason);
-
void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
void SaveCallerDoubles();
@@ -268,7 +246,6 @@ class LCodeGen: public LCodeGenBase {
LEnvironment* environment,
Deoptimizer::BailoutType bailout_type);
void DeoptimizeIf(Condition cc, LEnvironment* environment);
- void ApplyCheckIf(Condition cc, LBoundsCheck* check);
bool DeoptEveryNTimes() {
return FLAG_deopt_every_n_times != 0 && !info()->IsStub();
@@ -457,6 +434,7 @@ class LCodeGen: public LCodeGenBase {
}
MacroAssembler* masm() const { return masm_; }
+ Isolate* isolate() const { return masm_->isolate(); }
private:
int ArrayIndex(X87Register reg);
diff --git a/deps/v8/src/ia32/lithium-gap-resolver-ia32.cc b/deps/v8/src/ia32/lithium-gap-resolver-ia32.cc
index 01821d95fa..34b949085a 100644
--- a/deps/v8/src/ia32/lithium-gap-resolver-ia32.cc
+++ b/deps/v8/src/ia32/lithium-gap-resolver-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/ia32/lithium-gap-resolver-ia32.h b/deps/v8/src/ia32/lithium-gap-resolver-ia32.h
index 4aff241f43..0eca35b39c 100644
--- a/deps/v8/src/ia32/lithium-gap-resolver-ia32.h
+++ b/deps/v8/src/ia32/lithium-gap-resolver-ia32.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_IA32_LITHIUM_GAP_RESOLVER_IA32_H_
#define V8_IA32_LITHIUM_GAP_RESOLVER_IA32_H_
diff --git a/deps/v8/src/ia32/lithium-ia32.cc b/deps/v8/src/ia32/lithium-ia32.cc
index 696c6be6e8..3231095adb 100644
--- a/deps/v8/src/ia32/lithium-ia32.cc
+++ b/deps/v8/src/ia32/lithium-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -688,6 +665,8 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
!hinstr->HasObservableSideEffects();
if (needs_environment && !instr->HasEnvironment()) {
instr = AssignEnvironment(instr);
+ // We can't really figure out if the environment is needed or not.
+ instr->environment()->set_has_been_used();
}
return instr;
@@ -936,7 +915,8 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
// the it was just a plain use), so it is free to move the split child into
// the same register that is used for the use-at-start.
// See https://code.google.com/p/chromium/issues/detail?id=201590
- if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) {
+ if (!(instr->ClobbersRegisters() &&
+ instr->ClobbersDoubleRegisters(isolate()))) {
int fixed = 0;
int used_at_start = 0;
for (UseIterator it(instr); !it.Done(); it.Advance()) {
@@ -960,13 +940,13 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
if (FLAG_stress_environments && !instr->HasEnvironment()) {
instr = AssignEnvironment(instr);
}
- if (!CpuFeatures::IsSafeForSnapshot(SSE2) && instr->IsGoto() &&
+ if (!CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) && instr->IsGoto() &&
LGoto::cast(instr)->jumps_to_join()) {
// TODO(olivf) Since phis of spilled values are joined as registers
// (not in the stack slot), we need to allow the goto gaps to keep one
// x87 register alive. To ensure all other values are still spilled, we
// insert a fpu register barrier right before.
- LClobberDoubles* clobber = new(zone()) LClobberDoubles();
+ LClobberDoubles* clobber = new(zone()) LClobberDoubles(isolate());
clobber->set_hydrogen_value(current);
chunk_->AddInstruction(clobber, current_block_);
}
@@ -1365,7 +1345,7 @@ LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) {
}
-LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
+LInstruction* LChunkBuilder::DoDivI(HDiv* instr) {
ASSERT(instr->representation().IsSmiOrInteger32());
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
@@ -1377,8 +1357,7 @@ LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
instr->CheckFlag(HValue::kCanOverflow) ||
- (!instr->IsMathFloorOfDiv() &&
- !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+ !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
result = AssignEnvironment(result);
}
return result;
@@ -1442,13 +1421,31 @@ LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
}
+LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
+ ASSERT(instr->representation().IsSmiOrInteger32());
+ ASSERT(instr->left()->representation().Equals(instr->representation()));
+ ASSERT(instr->right()->representation().Equals(instr->representation()));
+ LOperand* dividend = UseFixed(instr->left(), eax);
+ LOperand* divisor = UseRegister(instr->right());
+ LOperand* temp = FixedTemp(edx);
+ LInstruction* result = DefineFixed(new(zone()) LFlooringDivI(
+ dividend, divisor, temp), eax);
+ if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+ instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+ instr->CheckFlag(HValue::kCanOverflow)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
+}
+
+
LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
if (instr->RightIsPowerOf2()) {
return DoFlooringDivByPowerOf2I(instr);
} else if (instr->right()->IsConstant()) {
return DoFlooringDivByConstI(instr);
} else {
- return DoDivI(instr);
+ return DoFlooringDivI(instr);
}
}
@@ -1658,6 +1655,8 @@ LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
LInstruction* LChunkBuilder::DoCompareNumericAndBranch(
HCompareNumericAndBranch* instr) {
+ LInstruction* goto_instr = CheckElideControlInstruction(instr);
+ if (goto_instr != NULL) return goto_instr;
Representation r = instr->representation();
if (r.IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().Equals(r));
@@ -1846,9 +1845,16 @@ LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
- return AssignEnvironment(new(zone()) LBoundsCheck(
- UseRegisterOrConstantAtStart(instr->index()),
- UseAtStart(instr->length())));
+ if (!FLAG_debug_code && instr->skip_check()) return NULL;
+ LOperand* index = UseRegisterOrConstantAtStart(instr->index());
+ LOperand* length = !index->IsConstantOperand()
+ ? UseOrConstantAtStart(instr->length())
+ : UseAtStart(instr->length());
+ LInstruction* result = new(zone()) LBoundsCheck(index, length);
+ if (!FLAG_debug_code || !instr->skip_check()) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -1882,29 +1888,23 @@ LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
LInstruction* LChunkBuilder::DoChange(HChange* instr) {
Representation from = instr->from();
Representation to = instr->to();
+ HValue* val = instr->value();
if (from.IsSmi()) {
if (to.IsTagged()) {
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
return DefineSameAsFirst(new(zone()) LDummyUse(value));
}
from = Representation::Tagged();
}
- // Only mark conversions that might need to allocate as calling rather than
- // all changes. This makes simple, non-allocating conversion not have to force
- // building a stack frame.
if (from.IsTagged()) {
if (to.IsDouble()) {
- LOperand* value = UseRegister(instr->value());
- // Temp register only necessary for minus zero check.
+ LOperand* value = UseRegister(val);
LOperand* temp = TempRegister();
- LInstruction* result = DefineAsRegister(
- new(zone()) LNumberUntagD(value, temp));
- if (!instr->value()->representation().IsSmi()) {
- result = AssignEnvironment(result);
- }
+ LInstruction* result =
+ DefineAsRegister(new(zone()) LNumberUntagD(value, temp));
+ if (!val->representation().IsSmi()) result = AssignEnvironment(result);
return result;
} else if (to.IsSmi()) {
- HValue* val = instr->value();
LOperand* value = UseRegister(val);
if (val->type().IsSmi()) {
return DefineSameAsFirst(new(zone()) LDummyUse(value));
@@ -1912,44 +1912,39 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
} else {
ASSERT(to.IsInteger32());
- HValue* val = instr->value();
if (val->type().IsSmi() || val->representation().IsSmi()) {
LOperand* value = UseRegister(val);
return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
} else {
+ LOperand* value = UseRegister(val);
bool truncating = instr->CanTruncateToInt32();
LOperand* xmm_temp =
- (CpuFeatures::IsSafeForSnapshot(SSE2) && !truncating)
+ (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) && !truncating)
? FixedTemp(xmm1) : NULL;
- LInstruction* result = DefineSameAsFirst(
- new(zone()) LTaggedToI(UseRegister(val), xmm_temp));
- if (!instr->value()->representation().IsSmi()) {
- // Note: Only deopts in deferred code.
- result = AssignEnvironment(result);
- }
+ LInstruction* result =
+ DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp));
+ if (!val->representation().IsSmi()) result = AssignEnvironment(result);
return result;
}
}
} else if (from.IsDouble()) {
if (to.IsTagged()) {
info()->MarkAsDeferredCalling();
- LOperand* value = UseRegisterAtStart(instr->value());
+ LOperand* value = UseRegisterAtStart(val);
LOperand* temp = FLAG_inline_new ? TempRegister() : NULL;
-
- // Make sure that temp and result_temp are different registers.
LUnallocated* result_temp = TempRegister();
LNumberTagD* result = new(zone()) LNumberTagD(value, temp);
return AssignPointerMap(Define(result, result_temp));
} else if (to.IsSmi()) {
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
return AssignEnvironment(
DefineAsRegister(new(zone()) LDoubleToSmi(value)));
} else {
ASSERT(to.IsInteger32());
bool truncating = instr->CanTruncateToInt32();
- bool needs_temp = CpuFeatures::IsSafeForSnapshot(SSE2) && !truncating;
- LOperand* value = needs_temp ?
- UseTempRegister(instr->value()) : UseRegister(instr->value());
+ bool needs_temp =
+ CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) && !truncating;
+ LOperand* value = needs_temp ? UseTempRegister(val) : UseRegister(val);
LOperand* temp = needs_temp ? TempRegister() : NULL;
LInstruction* result =
DefineAsRegister(new(zone()) LDoubleToI(value, temp));
@@ -1959,23 +1954,23 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
} else if (from.IsInteger32()) {
info()->MarkAsDeferredCalling();
if (to.IsTagged()) {
- HValue* val = instr->value();
- LOperand* value = UseRegister(val);
if (!instr->CheckFlag(HValue::kCanOverflow)) {
+ LOperand* value = UseRegister(val);
return DefineSameAsFirst(new(zone()) LSmiTag(value));
} else if (val->CheckFlag(HInstruction::kUint32)) {
+ LOperand* value = UseRegister(val);
LOperand* temp1 = TempRegister();
- LOperand* temp2 = CpuFeatures::IsSupported(SSE2) ? FixedTemp(xmm1)
- : NULL;
+ LOperand* temp2 =
+ CpuFeatures::IsSupported(SSE2) ? FixedTemp(xmm1) : NULL;
LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
return AssignPointerMap(DefineSameAsFirst(result));
} else {
+ LOperand* value = UseRegister(val);
LOperand* temp = TempRegister();
LNumberTagI* result = new(zone()) LNumberTagI(value, temp);
return AssignPointerMap(DefineSameAsFirst(result));
}
} else if (to.IsSmi()) {
- HValue* val = instr->value();
LOperand* value = UseRegister(val);
LInstruction* result = DefineSameAsFirst(new(zone()) LSmiTag(value));
if (instr->CheckFlag(HValue::kCanOverflow)) {
@@ -1984,13 +1979,12 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
return result;
} else {
ASSERT(to.IsDouble());
- if (instr->value()->CheckFlag(HInstruction::kUint32)) {
+ if (val->CheckFlag(HInstruction::kUint32)) {
LOperand* temp = FixedTemp(xmm1);
return DefineAsRegister(
- new(zone()) LUint32ToDouble(UseRegister(instr->value()), temp));
+ new(zone()) LUint32ToDouble(UseRegister(val), temp));
} else {
- return DefineAsRegister(
- new(zone()) LInteger32ToDouble(Use(instr->value())));
+ return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val)));
}
}
}
@@ -2001,7 +1995,9 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
LOperand* value = UseAtStart(instr->value());
- return AssignEnvironment(new(zone()) LCheckNonSmi(value));
+ LInstruction* result = new(zone()) LCheckNonSmi(value);
+ if (!instr->value()->IsHeapObject()) result = AssignEnvironment(result);
+ return result;
}
@@ -2031,16 +2027,12 @@ LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
- LOperand* value = NULL;
- if (!instr->CanOmitMapChecks()) {
- value = UseRegisterAtStart(instr->value());
- if (instr->has_migration_target()) info()->MarkAsDeferredCalling();
- }
- LCheckMaps* result = new(zone()) LCheckMaps(value);
- if (!instr->CanOmitMapChecks()) {
- // Note: Only deopts in deferred code.
- AssignEnvironment(result);
- if (instr->has_migration_target()) return AssignPointerMap(result);
+ if (instr->IsStabilityCheck()) return new(zone()) LCheckMaps;
+ LOperand* value = UseRegisterAtStart(instr->value());
+ LInstruction* result = AssignEnvironment(new(zone()) LCheckMaps(value));
+ if (instr->HasMigrationTarget()) {
+ info()->MarkAsDeferredCalling();
+ result = AssignPointerMap(result);
}
return result;
}
@@ -2266,7 +2258,7 @@ LOperand* LChunkBuilder::GetStoreKeyedValueOperand(HStoreKeyed* instr) {
return UseFixed(instr->value(), eax);
}
- if (!CpuFeatures::IsSafeForSnapshot(SSE2) &&
+ if (!CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) &&
IsDoubleOrFloatElementsKind(elements_kind)) {
return UseRegisterAtStart(instr->value());
}
@@ -2345,7 +2337,6 @@ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- LOperand* object = UseRegister(instr->object());
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
LOperand* object = UseRegister(instr->object());
LOperand* new_map_reg = TempRegister();
@@ -2355,10 +2346,11 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind(
new_map_reg, temp_reg);
return result;
} else {
+ LOperand* object = UseFixed(instr->object(), eax);
LOperand* context = UseFixed(instr->context(), esi);
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, context, NULL, NULL);
- return AssignPointerMap(result);
+ return MarkAsCall(result, instr);
}
}
@@ -2521,7 +2513,7 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
} else {
ASSERT(info()->IsStub());
CodeStubInterfaceDescriptor* descriptor =
- info()->code_stub()->GetInterfaceDescriptor(info()->isolate());
+ info()->code_stub()->GetInterfaceDescriptor();
int index = static_cast<int>(instr->index());
Register reg = descriptor->GetParameterRegister(index);
return DefineFixed(result, reg);
@@ -2642,6 +2634,7 @@ LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
HEnvironment* outer = current_block_->last_environment();
+ outer->set_ast_id(instr->ReturnId());
HConstant* undefined = graph()->GetConstantUndefined();
HEnvironment* inner = outer->CopyForInlining(instr->closure(),
instr->arguments_count(),
@@ -2702,7 +2695,9 @@ LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
LOperand* object = UseRegister(instr->object());
LOperand* index = UseTempRegister(instr->index());
- return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index));
+ LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index);
+ LInstruction* result = DefineSameAsFirst(load);
+ return AssignPointerMap(result);
}
diff --git a/deps/v8/src/ia32/lithium-ia32.h b/deps/v8/src/ia32/lithium-ia32.h
index 7964b7f6ee..fe6f79463e 100644
--- a/deps/v8/src/ia32/lithium-ia32.h
+++ b/deps/v8/src/ia32/lithium-ia32.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_IA32_LITHIUM_IA32_H_
#define V8_IA32_LITHIUM_IA32_H_
@@ -99,6 +76,7 @@ class LCodeGen;
V(DummyUse) \
V(FlooringDivByConstI) \
V(FlooringDivByPowerOf2I) \
+ V(FlooringDivI) \
V(ForInCacheArray) \
V(ForInPrepareMap) \
V(FunctionLiteral) \
@@ -260,11 +238,11 @@ class LInstruction : public ZoneObject {
// Interface to the register allocator and iterators.
bool ClobbersTemps() const { return IsCall(); }
bool ClobbersRegisters() const { return IsCall(); }
- virtual bool ClobbersDoubleRegisters() const {
+ virtual bool ClobbersDoubleRegisters(Isolate* isolate) const {
return IsCall() ||
// We only have rudimentary X87Stack tracking, thus in general
// cannot handle phi-nodes.
- (!CpuFeatures::IsSafeForSnapshot(SSE2) && IsControl());
+ (!CpuFeatures::IsSafeForSnapshot(isolate, SSE2) && IsControl());
}
virtual bool HasResult() const = 0;
@@ -399,9 +377,13 @@ class LInstructionGap V8_FINAL : public LGap {
class LClobberDoubles V8_FINAL : public LTemplateInstruction<0, 0, 0> {
public:
- LClobberDoubles() { ASSERT(!CpuFeatures::IsSafeForSnapshot(SSE2)); }
+ explicit LClobberDoubles(Isolate* isolate) {
+ ASSERT(!CpuFeatures::IsSafeForSnapshot(isolate, SSE2));
+ }
- virtual bool ClobbersDoubleRegisters() const { return true; }
+ virtual bool ClobbersDoubleRegisters(Isolate* isolate) const V8_OVERRIDE {
+ return true;
+ }
DECLARE_CONCRETE_INSTRUCTION(ClobberDoubles, "clobber-d")
};
@@ -417,7 +399,9 @@ class LGoto V8_FINAL : public LTemplateInstruction<0, 0, 0> {
virtual bool IsControl() const V8_OVERRIDE { return true; }
int block_id() const { return block_->block_id(); }
- virtual bool ClobbersDoubleRegisters() const { return false; }
+ virtual bool ClobbersDoubleRegisters(Isolate* isolate) const V8_OVERRIDE {
+ return false;
+ }
bool jumps_to_join() const { return block_->predecessors()->length() > 1; }
@@ -744,14 +728,14 @@ class LDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 2> {
class LDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
public:
- LDivI(LOperand* left, LOperand* right, LOperand* temp) {
- inputs_[0] = left;
- inputs_[1] = right;
+ LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
+ inputs_[0] = dividend;
+ inputs_[1] = divisor;
temps_[0] = temp;
}
- LOperand* left() { return inputs_[0]; }
- LOperand* right() { return inputs_[1]; }
+ LOperand* dividend() { return inputs_[0]; }
+ LOperand* divisor() { return inputs_[1]; }
LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
@@ -806,6 +790,23 @@ class LFlooringDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 3> {
};
+class LFlooringDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
+ public:
+ LFlooringDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
+ inputs_[0] = dividend;
+ inputs_[1] = divisor;
+ temps_[0] = temp;
+ }
+
+ LOperand* dividend() { return inputs_[0]; }
+ LOperand* divisor() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i")
+ DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+};
+
+
class LMulI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
public:
LMulI(LOperand* left, LOperand* right, LOperand* temp) {
@@ -1993,7 +1994,7 @@ class LCallRuntime V8_FINAL : public LTemplateInstruction<1, 1, 0> {
DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
- virtual bool ClobbersDoubleRegisters() const V8_OVERRIDE {
+ virtual bool ClobbersDoubleRegisters(Isolate* isolate) const V8_OVERRIDE {
return save_doubles() == kDontSaveFPRegs;
}
@@ -2190,11 +2191,6 @@ class LStoreNamedField V8_FINAL : public LTemplateInstruction<0, 2, 2> {
DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
-
- Handle<Map> transition() const { return hydrogen()->transition_map(); }
- Representation representation() const {
- return hydrogen()->field_representation();
- }
};
@@ -2403,7 +2399,7 @@ class LCheckInstanceType V8_FINAL : public LTemplateInstruction<0, 1, 1> {
class LCheckMaps V8_FINAL : public LTemplateInstruction<0, 1, 0> {
public:
- explicit LCheckMaps(LOperand* value) {
+ explicit LCheckMaps(LOperand* value = NULL) {
inputs_[0] = value;
}
@@ -2730,6 +2726,8 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
next_block_(NULL),
allocator_(allocator) { }
+ Isolate* isolate() const { return graph_->isolate(); }
+
// Build the sequence for the graph.
LPlatformChunk* Build();
@@ -2750,12 +2748,13 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
LInstruction* DoMathClz32(HUnaryMathOperation* instr);
LInstruction* DoDivByPowerOf2I(HDiv* instr);
LInstruction* DoDivByConstI(HDiv* instr);
- LInstruction* DoDivI(HBinaryOperation* instr);
+ LInstruction* DoDivI(HDiv* instr);
LInstruction* DoModByPowerOf2I(HMod* instr);
LInstruction* DoModByConstI(HMod* instr);
LInstruction* DoModI(HMod* instr);
LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr);
LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr);
+ LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr);
private:
enum Status {
diff --git a/deps/v8/src/ia32/macro-assembler-ia32.cc b/deps/v8/src/ia32/macro-assembler-ia32.cc
index 7847b3b398..f27927de96 100644
--- a/deps/v8/src/ia32/macro-assembler-ia32.cc
+++ b/deps/v8/src/ia32/macro-assembler-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -198,7 +175,7 @@ void MacroAssembler::RememberedSetHelper(
j(equal, &done, Label::kNear);
}
StoreBufferOverflowStub store_buffer_overflow =
- StoreBufferOverflowStub(save_fp);
+ StoreBufferOverflowStub(isolate(), save_fp);
CallStub(&store_buffer_overflow);
if (and_then == kReturnAtEnd) {
ret(0);
@@ -247,8 +224,8 @@ void MacroAssembler::ClampUint8(Register reg) {
void MacroAssembler::SlowTruncateToI(Register result_reg,
Register input_reg,
int offset) {
- DoubleToIStub stub(input_reg, result_reg, offset, true);
- call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
+ DoubleToIStub stub(isolate(), input_reg, result_reg, offset, true);
+ call(stub.GetCode(), RelocInfo::CODE_TARGET);
}
@@ -414,7 +391,7 @@ void MacroAssembler::TaggedToI(Register result_reg,
isolate()->factory()->heap_number_map());
j(not_equal, lost_precision, Label::kNear);
- if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
+ if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) {
ASSERT(!temp.is(no_xmm_reg));
CpuFeatureScope scope(this, SSE2);
@@ -634,7 +611,8 @@ void MacroAssembler::RecordWriteForMap(
// them.
lea(address, FieldOperand(object, HeapObject::kMapOffset));
mov(value, Immediate(map));
- RecordWriteStub stub(object, value, address, OMIT_REMEMBERED_SET, save_fp);
+ RecordWriteStub stub(isolate(), object, value, address, OMIT_REMEMBERED_SET,
+ save_fp);
CallStub(&stub);
bind(&done);
@@ -699,7 +677,8 @@ void MacroAssembler::RecordWrite(Register object,
&done,
Label::kNear);
- RecordWriteStub stub(object, value, address, remembered_set_action, fp_mode);
+ RecordWriteStub stub(isolate(), object, value, address, remembered_set_action,
+ fp_mode);
CallStub(&stub);
bind(&done);
@@ -713,14 +692,12 @@ void MacroAssembler::RecordWrite(Register object,
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
void MacroAssembler::DebugBreak() {
Move(eax, Immediate(0));
mov(ebx, Immediate(ExternalReference(Runtime::kDebugBreak, isolate())));
- CEntryStub ces(1);
- call(ces.GetCode(isolate()), RelocInfo::DEBUG_BREAK);
+ CEntryStub ces(isolate(), 1);
+ call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
}
-#endif
void MacroAssembler::Cvtsi2sd(XMMRegister dst, const Operand& src) {
@@ -1424,7 +1401,7 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
// Note: r0 will contain hash code
void MacroAssembler::GetNumberHash(Register r0, Register scratch) {
// Xor original key with a seed.
- if (Serializer::enabled()) {
+ if (Serializer::enabled(isolate())) {
ExternalReference roots_array_start =
ExternalReference::roots_array_start(isolate());
mov(scratch, Immediate(Heap::kHashSeedRootIndex));
@@ -2182,12 +2159,12 @@ void MacroAssembler::TryGetFunctionPrototype(Register function,
void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) {
ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs.
- call(stub->GetCode(isolate()), RelocInfo::CODE_TARGET, ast_id);
+ call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id);
}
void MacroAssembler::TailCallStub(CodeStub* stub) {
- jmp(stub->GetCode(isolate()), RelocInfo::CODE_TARGET);
+ jmp(stub->GetCode(), RelocInfo::CODE_TARGET);
}
@@ -2202,14 +2179,6 @@ bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
}
-void MacroAssembler::IllegalOperation(int num_arguments) {
- if (num_arguments > 0) {
- add(esp, Immediate(num_arguments * kPointerSize));
- }
- mov(eax, Immediate(isolate()->factory()->undefined_value()));
-}
-
-
void MacroAssembler::IndexFromHash(Register hash, Register index) {
// The assert checks that the constants for the maximum number of digits
// for an array index cached in the hash field and the number of bits
@@ -2235,10 +2204,7 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f,
// If the expected number of arguments of the runtime function is
// constant, we check that the actual number of arguments match the
// expectation.
- if (f->nargs >= 0 && f->nargs != num_arguments) {
- IllegalOperation(num_arguments);
- return;
- }
+ CHECK(f->nargs < 0 || f->nargs == num_arguments);
// TODO(1236192): Most runtime routines don't need the number of
// arguments passed in because it is constant. At some point we
@@ -2246,8 +2212,10 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f,
// smarter.
Move(eax, Immediate(num_arguments));
mov(ebx, Immediate(ExternalReference(f, isolate())));
- CEntryStub ces(1, CpuFeatures::IsSupported(SSE2) ? save_doubles
- : kDontSaveFPRegs);
+ CEntryStub ces(isolate(),
+ 1,
+ CpuFeatures::IsSupported(SSE2) ? save_doubles
+ : kDontSaveFPRegs);
CallStub(&ces);
}
@@ -2257,7 +2225,7 @@ void MacroAssembler::CallExternalReference(ExternalReference ref,
mov(eax, Immediate(num_arguments));
mov(ebx, Immediate(ref));
- CEntryStub stub(1);
+ CEntryStub stub(isolate(), 1);
CallStub(&stub);
}
@@ -2298,7 +2266,7 @@ void MacroAssembler::PrepareCallApiFunction(int argc) {
void MacroAssembler::CallApiFunctionAndReturn(
Register function_address,
- Address thunk_address,
+ ExternalReference thunk_ref,
Operand thunk_last_arg,
int stack_space,
Operand return_value_operand,
@@ -2329,17 +2297,15 @@ void MacroAssembler::CallApiFunctionAndReturn(
Label profiler_disabled;
Label end_profiler_check;
- bool* is_profiling_flag =
- isolate()->cpu_profiler()->is_profiling_address();
- STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
- mov(eax, Immediate(reinterpret_cast<Address>(is_profiling_flag)));
+ mov(eax, Immediate(ExternalReference::is_profiling_address(isolate())));
cmpb(Operand(eax, 0), 0);
j(zero, &profiler_disabled);
// Additional parameter is the address of the actual getter function.
mov(thunk_last_arg, function_address);
// Call the api function.
- call(thunk_address, RelocInfo::RUNTIME_ENTRY);
+ mov(eax, Immediate(thunk_ref));
+ call(eax);
jmp(&end_profiler_check);
bind(&profiler_disabled);
@@ -2451,8 +2417,8 @@ void MacroAssembler::CallApiFunctionAndReturn(
void MacroAssembler::JumpToExternalReference(const ExternalReference& ext) {
// Set the entry point and jump to the C entry runtime stub.
mov(ebx, Immediate(ext));
- CEntryStub ces(1);
- jmp(ces.GetCode(isolate()), RelocInfo::CODE_TARGET);
+ CEntryStub ces(isolate(), 1);
+ jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
}
diff --git a/deps/v8/src/ia32/macro-assembler-ia32.h b/deps/v8/src/ia32/macro-assembler-ia32.h
index 698c81fe83..f8c2401323 100644
--- a/deps/v8/src/ia32/macro-assembler-ia32.h
+++ b/deps/v8/src/ia32/macro-assembler-ia32.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_IA32_MACRO_ASSEMBLER_IA32_H_
#define V8_IA32_MACRO_ASSEMBLER_IA32_H_
@@ -221,12 +198,10 @@ class MacroAssembler: public Assembler {
Register scratch2,
SaveFPRegsMode save_fp);
-#ifdef ENABLE_DEBUGGER_SUPPORT
// ---------------------------------------------------------------------------
// Debugger Support
void DebugBreak();
-#endif
// Generates function and stub prologue code.
void Prologue(PrologueFrameMode frame_mode);
@@ -727,10 +702,6 @@ class MacroAssembler: public Assembler {
Label* miss,
bool miss_on_bound_function = false);
- // Generates code for reporting that an illegal operation has
- // occurred.
- void IllegalOperation(int num_arguments);
-
// Picks out an array index from the hash field.
// Register use:
// hash - holds the index's hash. Clobbered.
@@ -809,7 +780,7 @@ class MacroAssembler: public Assembler {
// caller-save registers. Restores context. On return removes
// stack_space * kPointerSize (GCed).
void CallApiFunctionAndReturn(Register function_address,
- Address thunk_address,
+ ExternalReference thunk_ref,
Operand thunk_last_arg,
int stack_space,
Operand return_value_operand,
@@ -1012,13 +983,6 @@ class MacroAssembler: public Assembler {
Register scratch,
AllocationFlags flags);
- // Helper for PopHandleScope. Allowed to perform a GC and returns
- // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and
- // possibly returns a failure object indicating an allocation failure.
- MUST_USE_RESULT MaybeObject* PopHandleScopeHelper(Register saved,
- Register scratch,
- bool gc_allowed);
-
// Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
void InNewSpace(Register object,
Register scratch,
diff --git a/deps/v8/src/ia32/regexp-macro-assembler-ia32.cc b/deps/v8/src/ia32/regexp-macro-assembler-ia32.cc
index 255df3285e..22c620e7c8 100644
--- a/deps/v8/src/ia32/regexp-macro-assembler-ia32.cc
+++ b/deps/v8/src/ia32/regexp-macro-assembler-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -1126,7 +1103,7 @@ int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address,
ASSERT(*return_address <=
re_code->instruction_start() + re_code->instruction_size());
- MaybeObject* result = Execution::HandleStackGuardInterrupt(isolate);
+ Object* result = Execution::HandleStackGuardInterrupt(isolate);
if (*code_handle != re_code) { // Return address no longer valid
int delta = code_handle->address() - re_code->address();
diff --git a/deps/v8/src/ia32/regexp-macro-assembler-ia32.h b/deps/v8/src/ia32/regexp-macro-assembler-ia32.h
index 3933336007..ab5b75b090 100644
--- a/deps/v8/src/ia32/regexp-macro-assembler-ia32.h
+++ b/deps/v8/src/ia32/regexp-macro-assembler-ia32.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_IA32_REGEXP_MACRO_ASSEMBLER_IA32_H_
#define V8_IA32_REGEXP_MACRO_ASSEMBLER_IA32_H_
diff --git a/deps/v8/src/ia32/simulator-ia32.cc b/deps/v8/src/ia32/simulator-ia32.cc
index b6f2847332..20edae83a2 100644
--- a/deps/v8/src/ia32/simulator-ia32.cc
+++ b/deps/v8/src/ia32/simulator-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Since there is no simulator for the ia32 architecture this file is empty.
diff --git a/deps/v8/src/ia32/simulator-ia32.h b/deps/v8/src/ia32/simulator-ia32.h
index 478d4ce5cb..10356284ec 100644
--- a/deps/v8/src/ia32/simulator-ia32.h
+++ b/deps/v8/src/ia32/simulator-ia32.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_IA32_SIMULATOR_IA32_H_
#define V8_IA32_SIMULATOR_IA32_H_
diff --git a/deps/v8/src/ia32/stub-cache-ia32.cc b/deps/v8/src/ia32/stub-cache-ia32.cc
index 1a745c7b7f..adc8cd59aa 100644
--- a/deps/v8/src/ia32/stub-cache-ia32.cc
+++ b/deps/v8/src/ia32/stub-cache-ia32.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -446,7 +423,7 @@ void StubCompiler::GenerateFastApiCall(MacroAssembler* masm,
__ mov(api_function_address, Immediate(function_address));
// Jump to stub.
- CallApiFunctionStub stub(is_store, call_data_undefined, argc);
+ CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
__ TailCallStub(&stub);
}
@@ -473,7 +450,7 @@ void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm,
JSGlobalObject::EnsurePropertyCell(global, name);
ASSERT(cell->value()->IsTheHole());
Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value();
- if (Serializer::enabled()) {
+ if (Serializer::enabled(masm->isolate())) {
__ mov(scratch, Immediate(cell));
__ cmp(FieldOperand(scratch, PropertyCell::kValueOffset),
Immediate(the_hole));
@@ -529,6 +506,21 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
__ JumpIfSmi(value_reg, miss_label);
+ HeapType* field_type = descriptors->GetFieldType(descriptor);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ Label do_store;
+ while (true) {
+ __ CompareMap(value_reg, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ j(not_equal, miss_label);
+ break;
+ }
+ __ j(equal, &do_store, Label::kNear);
+ }
+ __ bind(&do_store);
+ }
} else if (representation.IsDouble()) {
Label do_store, heap_number;
__ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow);
@@ -699,6 +691,21 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
__ JumpIfSmi(value_reg, miss_label);
+ HeapType* field_type = lookup->GetFieldType();
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ Label do_store;
+ while (true) {
+ __ CompareMap(value_reg, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ j(not_equal, miss_label);
+ break;
+ }
+ __ j(equal, &do_store, Label::kNear);
+ }
+ __ bind(&do_store);
+ }
} else if (representation.IsDouble()) {
// Load the double storage.
if (index < 0) {
@@ -824,7 +831,8 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
int depth = 0;
Handle<JSObject> current = Handle<JSObject>::null();
- if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant());
+ if (type->IsConstant()) current =
+ Handle<JSObject>::cast(type->AsConstant()->Value());
Handle<JSObject> prototype = Handle<JSObject>::null();
Handle<Map> current_map = receiver_map;
Handle<Map> holder_map(holder->map());
@@ -847,7 +855,7 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
name = factory()->InternalizeString(Handle<String>::cast(name));
}
ASSERT(current.is_null() ||
- current->property_dictionary()->FindEntry(*name) ==
+ current->property_dictionary()->FindEntry(name) ==
NameDictionary::kNotFound);
GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
@@ -1002,15 +1010,17 @@ void LoadStubCompiler::GenerateLoadField(Register reg,
Representation representation) {
if (!reg.is(receiver())) __ mov(receiver(), reg);
if (kind() == Code::LOAD_IC) {
- LoadFieldStub stub(field.is_inobject(holder),
+ LoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
field.translate(holder),
representation);
- GenerateTailCall(masm(), stub.GetCode(isolate()));
+ GenerateTailCall(masm(), stub.GetCode());
} else {
- KeyedLoadFieldStub stub(field.is_inobject(holder),
+ KeyedLoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
field.translate(holder),
representation);
- GenerateTailCall(masm(), stub.GetCode(isolate()));
+ GenerateTailCall(masm(), stub.GetCode());
}
}
@@ -1056,7 +1066,7 @@ void LoadStubCompiler::GenerateLoadCallback(
Address function_address = v8::ToCData<Address>(callback->getter());
__ mov(getter_address, Immediate(function_address));
- CallApiGetterStub stub;
+ CallApiGetterStub stub(isolate());
__ TailCallStub(&stub);
}
@@ -1167,17 +1177,6 @@ void LoadStubCompiler::GenerateLoadInterceptor(
}
-void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
- Label success;
- // Check that the object is a boolean.
- __ cmp(object, factory()->true_value());
- __ j(equal, &success);
- __ cmp(object, factory()->false_value());
- __ j(not_equal, miss);
- __ bind(&success);
-}
-
-
Handle<Code> StoreStubCompiler::CompileStoreCallback(
Handle<JSObject> object,
Handle<JSObject> holder,
@@ -1414,7 +1413,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
HandlerFrontendHeader(type, receiver(), global, name, &miss);
// Get the value from the cell.
- if (Serializer::enabled()) {
+ if (Serializer::enabled(isolate())) {
__ mov(eax, Immediate(cell));
__ mov(eax, FieldOperand(eax, PropertyCell::kValueOffset));
} else {
diff --git a/deps/v8/src/ic-inl.h b/deps/v8/src/ic-inl.h
index ebe0fb9b35..010df08c66 100644
--- a/deps/v8/src/ic-inl.h
+++ b/deps/v8/src/ic-inl.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_IC_INL_H_
#define V8_IC_INL_H_
@@ -42,7 +19,6 @@ Address IC::address() const {
// Get the address of the call.
Address result = Assembler::target_address_from_return_address(pc());
-#ifdef ENABLE_DEBUGGER_SUPPORT
Debug* debug = isolate()->debug();
// First check if any break points are active if not just return the address
// of the call.
@@ -68,9 +44,6 @@ Address IC::address() const {
// No break point here just return the address of the call.
return result;
}
-#else
- return result;
-#endif
}
@@ -79,7 +52,6 @@ ConstantPoolArray* IC::constant_pool() const {
return NULL;
} else {
Handle<ConstantPoolArray> result = raw_constant_pool_;
-#ifdef ENABLE_DEBUGGER_SUPPORT
Debug* debug = isolate()->debug();
// First check if any break points are active if not just return the
// original constant pool.
@@ -94,7 +66,6 @@ ConstantPoolArray* IC::constant_pool() const {
// constant pool for the original code instead of the breakpointed code.
return GetOriginalCode()->constant_pool();
}
-#endif
return *result;
}
}
diff --git a/deps/v8/src/ic.cc b/deps/v8/src/ic.cc
index a327173629..3897f88450 100644
--- a/deps/v8/src/ic.cc
+++ b/deps/v8/src/ic.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -31,11 +8,11 @@
#include "api.h"
#include "arguments.h"
#include "codegen.h"
+#include "conversions.h"
#include "execution.h"
#include "ic-inl.h"
#include "runtime.h"
#include "stub-cache.h"
-#include "v8conversions.h"
namespace v8 {
namespace internal {
@@ -91,9 +68,11 @@ void IC::TraceIC(const char* type,
}
JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
ExtraICState extra_state = new_target->extra_ic_state();
- const char* modifier =
- GetTransitionMarkModifier(
- KeyedStoreIC::GetKeyedAccessStoreMode(extra_state));
+ const char* modifier = "";
+ if (new_target->kind() == Code::KEYED_STORE_IC) {
+ modifier = GetTransitionMarkModifier(
+ KeyedStoreIC::GetKeyedAccessStoreMode(extra_state));
+ }
PrintF(" (%c->%c%s)",
TransitionMarkFromState(state()),
TransitionMarkFromState(new_state),
@@ -121,7 +100,8 @@ void IC::TraceIC(const char* type,
IC::IC(FrameDepth depth, Isolate* isolate)
: isolate_(isolate),
- target_set_(false) {
+ target_set_(false),
+ target_maps_set_(false) {
// To improve the performance of the (much used) IC code, we unfold a few
// levels of the stack frame iteration code. This yields a ~35% speedup when
// running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag.
@@ -166,7 +146,6 @@ IC::IC(FrameDepth depth, Isolate* isolate)
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
SharedFunctionInfo* IC::GetSharedFunctionInfo() const {
// Compute the JavaScript frame for the frame pointer of this IC
// structure. We need this to be able to find the function
@@ -197,7 +176,6 @@ Code* IC::GetOriginalCode() const {
ASSERT(original_code->IsCode());
return original_code;
}
-#endif
static bool HasInterceptorGetter(JSObject* object) {
@@ -216,7 +194,7 @@ static void LookupForRead(Handle<Object> object,
// Skip all the objects with named interceptors, but
// without actual getter.
while (true) {
- object->Lookup(*name, lookup);
+ object->Lookup(name, lookup);
// Besides normal conditions (property not found or it's not
// an interceptor), bail out if lookup is not cacheable: we won't
// be able to IC it anyway and regular lookup should work fine.
@@ -229,7 +207,7 @@ static void LookupForRead(Handle<Object> object,
return;
}
- holder->LocalLookupRealNamedProperty(*name, lookup);
+ holder->LocalLookupRealNamedProperty(name, lookup);
if (lookup->IsFound()) {
ASSERT(!lookup->IsInterceptor());
return;
@@ -248,12 +226,7 @@ static void LookupForRead(Handle<Object> object,
bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
Handle<String> name) {
- if (target()->is_keyed_stub()) {
- // Determine whether the failure is due to a name failure.
- if (!name->IsName()) return false;
- Name* stub_name = target()->FindFirstName();
- if (*name != stub_name) return false;
- }
+ if (!IsNameCompatibleWithMonomorphicPrototypeFailure(name)) return false;
InlineCacheHolderFlag cache_holder =
Code::ExtractCacheHolderFromFlags(target()->flags());
@@ -298,7 +271,7 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
// If the IC is shared between multiple receivers (slow dictionary mode), then
// the map cannot be deprecated and the stub invalidated.
if (cache_holder == OWN_MAP) {
- Map* old_map = target()->FindFirstMap();
+ Map* old_map = FirstTargetMap();
if (old_map == *map) return true;
if (old_map != NULL) {
if (old_map->is_deprecated()) return true;
@@ -312,7 +285,7 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
if (receiver->IsGlobalObject()) {
LookupResult lookup(isolate());
GlobalObject* global = GlobalObject::cast(*receiver);
- global->LocalLookupRealNamedProperty(*name, &lookup);
+ global->LocalLookupRealNamedProperty(name, &lookup);
if (!lookup.IsFound()) return false;
PropertyCell* cell = global->GetPropertyCell(&lookup);
return cell->type()->IsConstant();
@@ -336,6 +309,18 @@ void IC::TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name) {
}
+bool IC::IsNameCompatibleWithMonomorphicPrototypeFailure(Handle<Object> name) {
+ if (target()->is_keyed_stub()) {
+ // Determine whether the failure is due to a name failure.
+ if (!name->IsName()) return false;
+ Name* stub_name = target()->FindFirstName();
+ if (*name != stub_name) return false;
+ }
+
+ return true;
+}
+
+
void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) {
if (!name->IsString()) return;
if (state() != MONOMORPHIC) {
@@ -352,8 +337,9 @@ void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) {
// because of changes in the prototype chain to avoid hitting it
// again.
if (TryRemoveInvalidPrototypeDependentStub(
- receiver, Handle<String>::cast(name))) {
- return MarkMonomorphicPrototypeFailure();
+ receiver, Handle<String>::cast(name)) &&
+ TryMarkMonomorphicPrototypeFailure(name)) {
+ return;
}
// The builtins object is special. It only changes when JavaScript
@@ -366,22 +352,22 @@ void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) {
}
-Failure* IC::TypeError(const char* type,
- Handle<Object> object,
- Handle<Object> key) {
+MaybeHandle<Object> IC::TypeError(const char* type,
+ Handle<Object> object,
+ Handle<Object> key) {
HandleScope scope(isolate());
Handle<Object> args[2] = { key, object };
Handle<Object> error = isolate()->factory()->NewTypeError(
type, HandleVector(args, 2));
- return isolate()->Throw(*error);
+ return isolate()->Throw<Object>(error);
}
-Failure* IC::ReferenceError(const char* type, Handle<String> name) {
+MaybeHandle<Object> IC::ReferenceError(const char* type, Handle<String> name) {
HandleScope scope(isolate());
Handle<Object> error = isolate()->factory()->NewReferenceError(
type, HandleVector(&name, 1));
- return isolate()->Throw(*error);
+ return isolate()->Throw<Object>(error);
}
@@ -406,6 +392,10 @@ void IC::PostPatching(Address address, Code* target, Code* old_target) {
target->is_inline_cache_stub()) {
int delta = ComputeTypeInfoCountDelta(old_target->ic_state(),
target->ic_state());
+ // Call ICs don't have interesting state changes from this point
+ // of view.
+ ASSERT(target->kind() != Code::CALL_IC || delta == 0);
+
// Not all Code objects have TypeFeedbackInfo.
if (host->type_feedback_info()->IsTypeFeedbackInfo() && delta != 0) {
TypeFeedbackInfo* info =
@@ -426,6 +416,42 @@ void IC::PostPatching(Address address, Code* target, Code* old_target) {
}
+void IC::RegisterWeakMapDependency(Handle<Code> stub) {
+ if (FLAG_collect_maps && FLAG_weak_embedded_maps_in_ic &&
+ stub->CanBeWeakStub()) {
+ ASSERT(!stub->is_weak_stub());
+ MapHandleList maps;
+ stub->FindAllMaps(&maps);
+ if (maps.length() == 1 && stub->IsWeakObjectInIC(*maps.at(0))) {
+ Map::AddDependentIC(maps.at(0), stub);
+ stub->mark_as_weak_stub();
+ if (FLAG_enable_ool_constant_pool) {
+ stub->constant_pool()->set_weak_object_state(
+ ConstantPoolArray::WEAK_OBJECTS_IN_IC);
+ }
+ }
+ }
+}
+
+
+void IC::InvalidateMaps(Code* stub) {
+ ASSERT(stub->is_weak_stub());
+ stub->mark_as_invalidated_weak_stub();
+ Isolate* isolate = stub->GetIsolate();
+ Heap* heap = isolate->heap();
+ Object* undefined = heap->undefined_value();
+ int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
+ for (RelocIterator it(stub, mode_mask); !it.done(); it.next()) {
+ RelocInfo::Mode mode = it.rinfo()->rmode();
+ if (mode == RelocInfo::EMBEDDED_OBJECT &&
+ it.rinfo()->target_object()->IsMap()) {
+ it.rinfo()->set_target_object(undefined, SKIP_WRITE_BARRIER);
+ }
+ }
+ CPU::FlushICache(stub->instruction_start(), stub->instruction_size());
+}
+
+
void IC::Clear(Isolate* isolate, Address address,
ConstantPoolArray* constant_pool) {
Code* target = GetTargetAtAddress(address, constant_pool);
@@ -442,6 +468,8 @@ void IC::Clear(Isolate* isolate, Address address,
return StoreIC::Clear(isolate, address, target, constant_pool);
case Code::KEYED_STORE_IC:
return KeyedStoreIC::Clear(isolate, address, target, constant_pool);
+ case Code::CALL_IC:
+ return CallIC::Clear(isolate, address, target, constant_pool);
case Code::COMPARE_IC:
return CompareIC::Clear(isolate, address, target, constant_pool);
case Code::COMPARE_NIL_IC:
@@ -468,6 +496,15 @@ void KeyedLoadIC::Clear(Isolate* isolate,
}
+void CallIC::Clear(Isolate* isolate,
+ Address address,
+ Code* target,
+ ConstantPoolArray* constant_pool) {
+ // Currently, CallIC doesn't have state changes.
+ ASSERT(target->ic_state() == v8::internal::GENERIC);
+}
+
+
void LoadIC::Clear(Isolate* isolate,
Address address,
Code* target,
@@ -527,8 +564,7 @@ static bool MigrateDeprecated(Handle<Object> object) {
}
-MaybeObject* LoadIC::Load(Handle<Object> object,
- Handle<String> name) {
+MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<String> name) {
// If the object is undefined or null it's illegal to try to get any
// of its properties; throw a TypeError in that case.
if (object->IsUndefined() || object->IsNull()) {
@@ -538,14 +574,14 @@ MaybeObject* LoadIC::Load(Handle<Object> object,
if (FLAG_use_ic) {
// Use specialized code for getting prototype of functions.
if (object->IsJSFunction() &&
- name->Equals(isolate()->heap()->prototype_string()) &&
+ String::Equals(isolate()->factory()->prototype_string(), name) &&
Handle<JSFunction>::cast(object)->should_have_prototype()) {
Handle<Code> stub;
if (state() == UNINITIALIZED) {
stub = pre_monomorphic_stub();
} else if (state() == PREMONOMORPHIC) {
- FunctionPrototypeStub function_prototype_stub(kind());
- stub = function_prototype_stub.GetCode(isolate());
+ FunctionPrototypeStub function_prototype_stub(isolate(), kind());
+ stub = function_prototype_stub.GetCode();
} else if (state() != MEGAMORPHIC) {
ASSERT(state() != GENERIC);
stub = megamorphic_stub();
@@ -554,7 +590,7 @@ MaybeObject* LoadIC::Load(Handle<Object> object,
set_target(*stub);
if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n");
}
- return *Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object));
+ return Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object));
}
}
@@ -564,10 +600,13 @@ MaybeObject* LoadIC::Load(Handle<Object> object,
if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) {
// Rewrite to the generic keyed load stub.
if (FLAG_use_ic) set_target(*generic_stub());
- Handle<Object> result =
- Runtime::GetElementOrCharAt(isolate(), object, index);
- RETURN_IF_EMPTY_HANDLE(isolate(), result);
- return *result;
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate(),
+ result,
+ Runtime::GetElementOrCharAt(isolate(), object, index),
+ Object);
+ return result;
}
bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic;
@@ -589,17 +628,19 @@ MaybeObject* LoadIC::Load(Handle<Object> object,
PropertyAttributes attr;
// Get the property.
- Handle<Object> result =
- Object::GetProperty(object, object, &lookup, name, &attr);
- RETURN_IF_EMPTY_HANDLE(isolate(), result);
- // If the property is not present, check if we need to throw an
- // exception.
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate(),
+ result,
+ Object::GetProperty(object, object, &lookup, name, &attr),
+ Object);
+ // If the property is not present, check if we need to throw an exception.
if ((lookup.IsInterceptor() || lookup.IsHandler()) &&
attr == ABSENT && IsUndeclaredGlobal(object)) {
return ReferenceError("not_defined", name);
}
- return *result;
+ return result;
}
@@ -624,17 +665,18 @@ bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
TypeHandleList types;
CodeHandleList handlers;
- target()->FindAllTypes(&types);
+ TargetTypes(&types);
int number_of_types = types.length();
int deprecated_types = 0;
int handler_to_overwrite = -1;
for (int i = 0; i < number_of_types; i++) {
Handle<HeapType> current_type = types.at(i);
- if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) {
+ if (current_type->IsClass() &&
+ current_type->AsClass()->Map()->is_deprecated()) {
// Filter out deprecated maps to ensure their instances get migrated.
++deprecated_types;
- } else if (type->IsCurrently(current_type)) {
+ } else if (type->NowIs(current_type)) {
// If the receiver type is already in the polymorphic IC, this indicates
// there was a prototoype chain failure. In that case, just overwrite the
// handler.
@@ -642,8 +684,8 @@ bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
} else if (handler_to_overwrite == -1 &&
current_type->IsClass() &&
type->IsClass() &&
- IsTransitionOfMonomorphicTarget(*current_type->AsClass(),
- *type->AsClass())) {
+ IsTransitionOfMonomorphicTarget(*current_type->AsClass()->Map(),
+ *type->AsClass()->Map())) {
handler_to_overwrite = i;
}
}
@@ -658,7 +700,7 @@ bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
number_of_valid_types++;
if (handler_to_overwrite >= 0) {
handlers.Set(handler_to_overwrite, code);
- if (!type->IsCurrently(types.at(handler_to_overwrite))) {
+ if (!type->NowIs(types.at(handler_to_overwrite))) {
types.Set(handler_to_overwrite, type);
}
} else {
@@ -676,19 +718,20 @@ bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
Handle<HeapType> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) {
return object->IsJSGlobalObject()
? HeapType::Constant(Handle<JSGlobalObject>::cast(object), isolate)
- : HeapType::OfCurrently(object, isolate);
+ : HeapType::NowOf(object, isolate);
}
Handle<Map> IC::TypeToMap(HeapType* type, Isolate* isolate) {
if (type->Is(HeapType::Number()))
return isolate->factory()->heap_number_map();
- if (type->Is(HeapType::Boolean())) return isolate->factory()->oddball_map();
+ if (type->Is(HeapType::Boolean())) return isolate->factory()->boolean_map();
if (type->IsConstant()) {
- return handle(Handle<JSGlobalObject>::cast(type->AsConstant())->map());
+ return handle(
+ Handle<JSGlobalObject>::cast(type->AsConstant()->Value())->map());
}
ASSERT(type->IsClass());
- return type->AsClass();
+ return type->AsClass()->Map();
}
@@ -727,7 +770,7 @@ void IC::UpdateMonomorphicIC(Handle<HeapType> type,
void IC::CopyICToMegamorphicCache(Handle<String> name) {
TypeHandleList types;
CodeHandleList handlers;
- target()->FindAllTypes(&types);
+ TargetTypes(&types);
if (!target()->FindHandlers(&handlers, types.length())) return;
for (int i = 0; i < types.length(); i++) {
UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i));
@@ -800,11 +843,11 @@ Handle<Code> LoadIC::SimpleFieldLoad(int offset,
bool inobject,
Representation representation) {
if (kind() == Code::LOAD_IC) {
- LoadFieldStub stub(inobject, offset, representation);
- return stub.GetCode(isolate());
+ LoadFieldStub stub(isolate(), inobject, offset, representation);
+ return stub.GetCode();
} else {
- KeyedLoadFieldStub stub(inobject, offset, representation);
- return stub.GetCode(isolate());
+ KeyedLoadFieldStub stub(isolate(), inobject, offset, representation);
+ return stub.GetCode();
}
}
@@ -880,19 +923,20 @@ Handle<Code> LoadIC::CompileHandler(LookupResult* lookup,
Handle<String> name,
Handle<Object> unused,
InlineCacheHolderFlag cache_holder) {
- if (object->IsString() && name->Equals(isolate()->heap()->length_string())) {
+ if (object->IsString() &&
+ String::Equals(isolate()->factory()->length_string(), name)) {
int length_index = String::kLengthOffset / kPointerSize;
return SimpleFieldLoad(length_index);
}
if (object->IsStringWrapper() &&
- name->Equals(isolate()->heap()->length_string())) {
+ String::Equals(isolate()->factory()->length_string(), name)) {
if (kind() == Code::LOAD_IC) {
- StringLengthStub string_length_stub;
- return string_length_stub.GetCode(isolate());
+ StringLengthStub string_length_stub(isolate());
+ return string_length_stub.GetCode();
} else {
- KeyedStringLengthStub string_length_stub;
- return string_length_stub.GetCode(isolate());
+ KeyedStringLengthStub string_length_stub(isolate());
+ return string_length_stub.GetCode();
}
}
@@ -981,9 +1025,7 @@ Handle<Code> LoadIC::CompileHandler(LookupResult* lookup,
return compiler.CompileLoadViaGetter(type, holder, name, function);
}
// TODO(dcarney): Handle correctly.
- if (callback->IsDeclaredAccessorInfo()) break;
- ASSERT(callback->IsForeign());
- // No IC support for old-style native accessors.
+ ASSERT(callback->IsDeclaredAccessorInfo());
break;
}
case INTERCEPTOR:
@@ -1028,19 +1070,13 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) {
Handle<Map> receiver_map(receiver->map(), isolate());
MapHandleList target_receiver_maps;
- if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) {
- // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
- // yet will do so and stay there.
- return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
- }
-
if (target().is_identical_to(string_stub())) {
target_receiver_maps.Add(isolate()->factory()->string_map());
} else {
- target()->FindAllMaps(&target_receiver_maps);
- if (target_receiver_maps.length() == 0) {
- return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
- }
+ TargetMaps(&target_receiver_maps);
+ }
+ if (target_receiver_maps.length() == 0) {
+ return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
}
// The first time a receiver is seen that is a transitioned version of the
@@ -1080,12 +1116,19 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) {
}
-MaybeObject* KeyedLoadIC::Load(Handle<Object> object, Handle<Object> key) {
+MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
+ Handle<Object> key) {
if (MigrateDeprecated(object)) {
- return Runtime::GetObjectPropertyOrFail(isolate(), object, key);
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate(),
+ result,
+ Runtime::GetObjectProperty(isolate(), object, key),
+ Object);
+ return result;
}
- MaybeObject* maybe_object = NULL;
+ Handle<Object> load_handle;
Handle<Code> stub = generic_stub();
// Check for non-string values that can be converted into an
@@ -1093,8 +1136,11 @@ MaybeObject* KeyedLoadIC::Load(Handle<Object> object, Handle<Object> key) {
key = TryConvertKey(key, isolate());
if (key->IsInternalizedString()) {
- maybe_object = LoadIC::Load(object, Handle<String>::cast(key));
- if (maybe_object->IsFailure()) return maybe_object;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate(),
+ load_handle,
+ LoadIC::Load(object, Handle<String>::cast(key)),
+ Object);
} else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) {
if (object->IsString() && key->IsNumber()) {
if (state() == UNINITIALIZED) stub = string_stub();
@@ -1105,7 +1151,7 @@ MaybeObject* KeyedLoadIC::Load(Handle<Object> object, Handle<Object> key) {
stub = sloppy_arguments_stub();
} else if (receiver->HasIndexedInterceptor()) {
stub = indexed_interceptor_stub();
- } else if (!key->ToSmi()->IsFailure() &&
+ } else if (!Object::ToSmi(isolate(), key).is_null() &&
(!target().is_identical_to(sloppy_arguments_stub()))) {
stub = LoadElementStub(receiver);
}
@@ -1120,8 +1166,14 @@ MaybeObject* KeyedLoadIC::Load(Handle<Object> object, Handle<Object> key) {
TRACE_IC("LoadIC", key);
}
- if (maybe_object != NULL) return maybe_object;
- return Runtime::GetObjectPropertyOrFail(isolate(), object, key);
+ if (!load_handle.is_null()) return load_handle;
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate(),
+ result,
+ Runtime::GetObjectProperty(isolate(), object, key),
+ Object);
+ return result;
}
@@ -1131,10 +1183,10 @@ static bool LookupForWrite(Handle<JSObject> receiver,
LookupResult* lookup,
IC* ic) {
Handle<JSObject> holder = receiver;
- receiver->Lookup(*name, lookup);
+ receiver->Lookup(name, lookup);
if (lookup->IsFound()) {
if (lookup->IsInterceptor() && !HasInterceptorSetter(lookup->holder())) {
- receiver->LocalLookupRealNamedProperty(*name, lookup);
+ receiver->LocalLookupRealNamedProperty(name, lookup);
if (!lookup->IsFound()) return false;
}
@@ -1160,9 +1212,7 @@ static bool LookupForWrite(Handle<JSObject> receiver,
// chain check. This avoids a double lookup, but requires us to pass in the
// receiver when trying to fetch extra information from the transition.
receiver->map()->LookupTransition(*holder, *name, lookup);
- if (!lookup->IsTransition()) return false;
- PropertyDetails target_details = lookup->GetTransitionDetails();
- if (target_details.IsReadOnly()) return false;
+ if (!lookup->IsTransition() || lookup->IsReadOnly()) return false;
// If the value that's being stored does not fit in the field that the
// instance would transition to, create a new transition that fits the value.
@@ -1171,30 +1221,38 @@ static bool LookupForWrite(Handle<JSObject> receiver,
// Ensure the instance and its map were migrated before trying to update the
// transition target.
ASSERT(!receiver->map()->is_deprecated());
- if (!value->FitsRepresentation(target_details.representation())) {
+ if (!lookup->CanHoldValue(value)) {
Handle<Map> target(lookup->GetTransitionTarget());
+ Representation field_representation = value->OptimalRepresentation();
+ Handle<HeapType> field_type = value->OptimalType(
+ lookup->isolate(), field_representation);
Map::GeneralizeRepresentation(
target, target->LastAdded(),
- value->OptimalRepresentation(), FORCE_FIELD);
+ field_representation, field_type, FORCE_FIELD);
// Lookup the transition again since the transition tree may have changed
// entirely by the migration above.
receiver->map()->LookupTransition(*holder, *name, lookup);
if (!lookup->IsTransition()) return false;
- ic->MarkMonomorphicPrototypeFailure();
+ return ic->TryMarkMonomorphicPrototypeFailure(name);
}
+
return true;
}
-MaybeObject* StoreIC::Store(Handle<Object> object,
- Handle<String> name,
- Handle<Object> value,
- JSReceiver::StoreFromKeyed store_mode) {
+MaybeHandle<Object> StoreIC::Store(Handle<Object> object,
+ Handle<String> name,
+ Handle<Object> value,
+ JSReceiver::StoreFromKeyed store_mode) {
if (MigrateDeprecated(object) || object->IsJSProxy()) {
- Handle<Object> result = JSReceiver::SetProperty(
- Handle<JSReceiver>::cast(object), name, value, NONE, strict_mode());
- RETURN_IF_EMPTY_HANDLE(isolate(), result);
- return *result;
+ Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate(),
+ result,
+ JSReceiver::SetProperty(receiver, name, value, NONE, strict_mode()),
+ Object);
+ return result;
}
// If the object is undefined or null it's illegal to try to set any
@@ -1205,31 +1263,38 @@ MaybeObject* StoreIC::Store(Handle<Object> object,
// The length property of string values is read-only. Throw in strict mode.
if (strict_mode() == STRICT && object->IsString() &&
- name->Equals(isolate()->heap()->length_string())) {
+ String::Equals(isolate()->factory()->length_string(), name)) {
return TypeError("strict_read_only_property", object, name);
}
// Ignore other stores where the receiver is not a JSObject.
// TODO(1475): Must check prototype chains of object wrappers.
- if (!object->IsJSObject()) return *value;
+ if (!object->IsJSObject()) return value;
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
// Check if the given name is an array index.
uint32_t index;
if (name->AsArrayIndex(&index)) {
- Handle<Object> result =
- JSObject::SetElement(receiver, index, value, NONE, strict_mode());
- RETURN_IF_EMPTY_HANDLE(isolate(), result);
- return *value;
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate(),
+ result,
+ JSObject::SetElement(receiver, index, value, NONE, strict_mode()),
+ Object);
+ return value;
}
// Observed objects are always modified through the runtime.
if (receiver->map()->is_observed()) {
- Handle<Object> result = JSReceiver::SetProperty(
- receiver, name, value, NONE, strict_mode(), store_mode);
- RETURN_IF_EMPTY_HANDLE(isolate(), result);
- return *result;
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate(),
+ result,
+ JSReceiver::SetProperty(
+ receiver, name, value, NONE, strict_mode(), store_mode),
+ Object);
+ return result;
}
LookupResult lookup(isolate());
@@ -1257,10 +1322,31 @@ MaybeObject* StoreIC::Store(Handle<Object> object,
}
// Set the property.
- Handle<Object> result = JSReceiver::SetProperty(
- receiver, name, value, NONE, strict_mode(), store_mode);
- RETURN_IF_EMPTY_HANDLE(isolate(), result);
- return *result;
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate(),
+ result,
+ JSReceiver::SetProperty(
+ receiver, name, value, NONE, strict_mode(), store_mode),
+ Object);
+ return result;
+}
+
+
+void CallIC::State::Print(StringStream* stream) const {
+ stream->Add("(args(%d), ",
+ argc_);
+ stream->Add("%s, ",
+ call_type_ == CallIC::METHOD ? "METHOD" : "FUNCTION");
+}
+
+
+Handle<Code> CallIC::initialize_stub(Isolate* isolate,
+ int argc,
+ CallType call_type) {
+ CallICStub stub(isolate, State::DefaultCallState(argc, call_type));
+ Handle<Code> code = stub.GetCode();
+ return code;
}
@@ -1319,93 +1405,80 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
Handle<JSObject> holder(lookup->holder());
// Handlers do not use strict mode.
StoreStubCompiler compiler(isolate(), SLOPPY, kind());
- switch (lookup->type()) {
- case FIELD:
- return compiler.CompileStoreField(receiver, lookup, name);
- case TRANSITION: {
- // Explicitly pass in the receiver map since LookupForWrite may have
- // stored something else than the receiver in the holder.
- Handle<Map> transition(lookup->GetTransitionTarget());
- PropertyDetails details = transition->GetLastDescriptorDetails();
-
- if (details.type() == CALLBACKS || details.attributes() != NONE) break;
+ if (lookup->IsTransition()) {
+ // Explicitly pass in the receiver map since LookupForWrite may have
+ // stored something else than the receiver in the holder.
+ Handle<Map> transition(lookup->GetTransitionTarget());
+ PropertyDetails details = lookup->GetPropertyDetails();
+ if (details.type() != CALLBACKS && details.attributes() == NONE) {
return compiler.CompileStoreTransition(
receiver, lookup, transition, name);
}
- case NORMAL:
- if (kind() == Code::KEYED_STORE_IC) break;
- if (receiver->IsJSGlobalProxy() || receiver->IsGlobalObject()) {
- // The stub generated for the global object picks the value directly
- // from the property cell. So the property must be directly on the
- // global object.
- Handle<GlobalObject> global = receiver->IsJSGlobalProxy()
- ? handle(GlobalObject::cast(receiver->GetPrototype()))
- : Handle<GlobalObject>::cast(receiver);
- Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate());
- Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value);
- StoreGlobalStub stub(
- union_type->IsConstant(), receiver->IsJSGlobalProxy());
- Handle<Code> code = stub.GetCodeCopyFromTemplate(
- isolate(), global, cell);
- // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
- HeapObject::UpdateMapCodeCache(receiver, name, code);
- return code;
- }
- ASSERT(holder.is_identical_to(receiver));
- return isolate()->builtins()->StoreIC_Normal();
- case CALLBACKS: {
- Handle<Object> callback(lookup->GetCallbackObject(), isolate());
- if (callback->IsExecutableAccessorInfo()) {
- Handle<ExecutableAccessorInfo> info =
- Handle<ExecutableAccessorInfo>::cast(callback);
- if (v8::ToCData<Address>(info->setter()) == 0) break;
- if (!holder->HasFastProperties()) break;
- if (!info->IsCompatibleReceiver(*receiver)) break;
- return compiler.CompileStoreCallback(receiver, holder, name, info);
- } else if (callback->IsAccessorPair()) {
- Handle<Object> setter(
- Handle<AccessorPair>::cast(callback)->setter(), isolate());
- if (!setter->IsJSFunction()) break;
- if (holder->IsGlobalObject()) break;
- if (!holder->HasFastProperties()) break;
- Handle<JSFunction> function = Handle<JSFunction>::cast(setter);
- CallOptimization call_optimization(function);
- if (call_optimization.is_simple_api_call() &&
- call_optimization.IsCompatibleReceiver(receiver, holder)) {
- return compiler.CompileStoreCallback(
- receiver, holder, name, call_optimization);
+ } else {
+ switch (lookup->type()) {
+ case FIELD:
+ return compiler.CompileStoreField(receiver, lookup, name);
+ case NORMAL:
+ if (kind() == Code::KEYED_STORE_IC) break;
+ if (receiver->IsJSGlobalProxy() || receiver->IsGlobalObject()) {
+ // The stub generated for the global object picks the value directly
+ // from the property cell. So the property must be directly on the
+ // global object.
+ Handle<GlobalObject> global = receiver->IsJSGlobalProxy()
+ ? handle(GlobalObject::cast(receiver->GetPrototype()))
+ : Handle<GlobalObject>::cast(receiver);
+ Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate());
+ Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value);
+ StoreGlobalStub stub(
+ isolate(), union_type->IsConstant(), receiver->IsJSGlobalProxy());
+ Handle<Code> code = stub.GetCodeCopyFromTemplate(global, cell);
+ // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
+ HeapObject::UpdateMapCodeCache(receiver, name, code);
+ return code;
}
- return compiler.CompileStoreViaSetter(
- receiver, holder, name, Handle<JSFunction>::cast(setter));
- }
- // TODO(dcarney): Handle correctly.
- if (callback->IsDeclaredAccessorInfo()) break;
- ASSERT(callback->IsForeign());
-
- // Use specialized code for setting the length of arrays with fast
- // properties. Slow properties might indicate redefinition of the length
- // property.
- if (receiver->IsJSArray() &&
- name->Equals(isolate()->heap()->length_string()) &&
- Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
- receiver->HasFastProperties()) {
- return compiler.CompileStoreArrayLength(receiver, lookup, name);
+ ASSERT(holder.is_identical_to(receiver));
+ return isolate()->builtins()->StoreIC_Normal();
+ case CALLBACKS: {
+ Handle<Object> callback(lookup->GetCallbackObject(), isolate());
+ if (callback->IsExecutableAccessorInfo()) {
+ Handle<ExecutableAccessorInfo> info =
+ Handle<ExecutableAccessorInfo>::cast(callback);
+ if (v8::ToCData<Address>(info->setter()) == 0) break;
+ if (!holder->HasFastProperties()) break;
+ if (!info->IsCompatibleReceiver(*receiver)) break;
+ return compiler.CompileStoreCallback(receiver, holder, name, info);
+ } else if (callback->IsAccessorPair()) {
+ Handle<Object> setter(
+ Handle<AccessorPair>::cast(callback)->setter(), isolate());
+ if (!setter->IsJSFunction()) break;
+ if (holder->IsGlobalObject()) break;
+ if (!holder->HasFastProperties()) break;
+ Handle<JSFunction> function = Handle<JSFunction>::cast(setter);
+ CallOptimization call_optimization(function);
+ if (call_optimization.is_simple_api_call() &&
+ call_optimization.IsCompatibleReceiver(receiver, holder)) {
+ return compiler.CompileStoreCallback(
+ receiver, holder, name, call_optimization);
+ }
+ return compiler.CompileStoreViaSetter(
+ receiver, holder, name, Handle<JSFunction>::cast(setter));
+ }
+ // TODO(dcarney): Handle correctly.
+ ASSERT(callback->IsDeclaredAccessorInfo());
+ break;
}
-
- // No IC support for old-style native accessors.
- break;
+ case INTERCEPTOR:
+ if (kind() == Code::KEYED_STORE_IC) break;
+ ASSERT(HasInterceptorSetter(*holder));
+ return compiler.CompileStoreInterceptor(receiver, name);
+ case CONSTANT:
+ break;
+ case NONEXISTENT:
+ case HANDLER:
+ UNREACHABLE();
+ break;
}
- case INTERCEPTOR:
- if (kind() == Code::KEYED_STORE_IC) break;
- ASSERT(HasInterceptorSetter(*holder));
- return compiler.CompileStoreInterceptor(receiver, name);
- case CONSTANT:
- break;
- case NONEXISTENT:
- case HANDLER:
- UNREACHABLE();
- break;
}
return slow_stub();
}
@@ -1422,24 +1495,16 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
}
Handle<Map> receiver_map(receiver->map(), isolate());
- if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) {
- // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
- // yet will do so and stay there.
- Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode);
+ MapHandleList target_receiver_maps;
+ TargetMaps(&target_receiver_maps);
+ if (target_receiver_maps.length() == 0) {
+ Handle<Map> monomorphic_map =
+ ComputeTransitionedMap(receiver_map, store_mode);
store_mode = GetNonTransitioningStoreMode(store_mode);
return isolate()->stub_cache()->ComputeKeyedStoreElement(
monomorphic_map, strict_mode(), store_mode);
}
- MapHandleList target_receiver_maps;
- target()->FindAllMaps(&target_receiver_maps);
- if (target_receiver_maps.length() == 0) {
- // In the case that there is a non-map-specific IC is installed (e.g. keyed
- // stores into properties in dictionary mode), then there will be not
- // receiver maps in the target.
- return generic_stub();
- }
-
// There are several special cases where an IC that is MONOMORPHIC can still
// transition to a different GetNonTransitioningStoreMode IC that handles a
// superset of the original IC. Handle those here if the receiver map hasn't
@@ -1450,7 +1515,8 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
if (state() == MONOMORPHIC) {
Handle<Map> transitioned_receiver_map = receiver_map;
if (IsTransitionStoreMode(store_mode)) {
- transitioned_receiver_map = ComputeTransitionedMap(receiver, store_mode);
+ transitioned_receiver_map =
+ ComputeTransitionedMap(receiver_map, store_mode);
}
if ((receiver_map.is_identical_to(previous_receiver_map) &&
IsTransitionStoreMode(store_mode)) ||
@@ -1482,7 +1548,7 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
if (IsTransitionStoreMode(store_mode)) {
Handle<Map> transitioned_receiver_map =
- ComputeTransitionedMap(receiver, store_mode);
+ ComputeTransitionedMap(receiver_map, store_mode);
map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps,
transitioned_receiver_map);
}
@@ -1538,36 +1604,35 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
Handle<Map> KeyedStoreIC::ComputeTransitionedMap(
- Handle<JSObject> receiver,
+ Handle<Map> map,
KeyedAccessStoreMode store_mode) {
switch (store_mode) {
case STORE_TRANSITION_SMI_TO_OBJECT:
case STORE_TRANSITION_DOUBLE_TO_OBJECT:
case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT:
case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT:
- return JSObject::GetElementsTransitionMap(receiver, FAST_ELEMENTS);
+ return Map::TransitionElementsTo(map, FAST_ELEMENTS);
case STORE_TRANSITION_SMI_TO_DOUBLE:
case STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE:
- return JSObject::GetElementsTransitionMap(receiver, FAST_DOUBLE_ELEMENTS);
+ return Map::TransitionElementsTo(map, FAST_DOUBLE_ELEMENTS);
case STORE_TRANSITION_HOLEY_SMI_TO_OBJECT:
case STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT:
case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT:
case STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT:
- return JSObject::GetElementsTransitionMap(receiver,
- FAST_HOLEY_ELEMENTS);
+ return Map::TransitionElementsTo(map, FAST_HOLEY_ELEMENTS);
case STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE:
case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE:
- return JSObject::GetElementsTransitionMap(receiver,
- FAST_HOLEY_DOUBLE_ELEMENTS);
+ return Map::TransitionElementsTo(map, FAST_HOLEY_DOUBLE_ELEMENTS);
case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
- ASSERT(receiver->map()->has_external_array_elements());
+ ASSERT(map->has_external_array_elements());
// Fall through
case STORE_NO_TRANSITION_HANDLE_COW:
case STANDARD_STORE:
case STORE_AND_GROW_NO_TRANSITION:
- return Handle<Map>(receiver->map(), isolate());
+ return map;
}
- return Handle<Map>::null();
+ UNREACHABLE();
+ return MaybeHandle<Map>().ToHandleChecked();
}
@@ -1584,9 +1649,7 @@ bool IsOutOfBoundsAccess(Handle<JSObject> receiver,
KeyedAccessStoreMode KeyedStoreIC::GetStoreMode(Handle<JSObject> receiver,
Handle<Object> key,
Handle<Object> value) {
- ASSERT(!key->ToSmi()->IsFailure());
- Smi* smi_key = NULL;
- key->ToSmi()->To(&smi_key);
+ Handle<Smi> smi_key = Object::ToSmi(isolate(), key).ToHandleChecked();
int index = smi_key->value();
bool oob_access = IsOutOfBoundsAccess(receiver, index);
// Don't consider this a growing store if the store would send the receiver to
@@ -1659,34 +1722,39 @@ KeyedAccessStoreMode KeyedStoreIC::GetStoreMode(Handle<JSObject> receiver,
}
-MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
- Handle<Object> key,
- Handle<Object> value) {
+MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
+ Handle<Object> key,
+ Handle<Object> value) {
if (MigrateDeprecated(object)) {
- Handle<Object> result = Runtime::SetObjectProperty(isolate(), object,
- key,
- value,
- NONE,
- strict_mode());
- RETURN_IF_EMPTY_HANDLE(isolate(), result);
- return *result;
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate(),
+ result,
+ Runtime::SetObjectProperty(
+ isolate(), object, key, value, NONE, strict_mode()),
+ Object);
+ return result;
}
// Check for non-string values that can be converted into an
// internalized string directly or is representable as a smi.
key = TryConvertKey(key, isolate());
- MaybeObject* maybe_object = NULL;
+ Handle<Object> store_handle;
Handle<Code> stub = generic_stub();
if (key->IsInternalizedString()) {
- maybe_object = StoreIC::Store(object,
- Handle<String>::cast(key),
- value,
- JSReceiver::MAY_BE_STORE_FROM_KEYED);
- if (maybe_object->IsFailure()) return maybe_object;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate(),
+ store_handle,
+ StoreIC::Store(object,
+ Handle<String>::cast(key),
+ value,
+ JSReceiver::MAY_BE_STORE_FROM_KEYED),
+ Object);
} else {
bool use_ic = FLAG_use_ic &&
+ !object->IsStringWrapper() &&
!object->IsAccessCheckNeeded() &&
!object->IsJSGlobalProxy() &&
!(object->IsJSObject() &&
@@ -1704,7 +1772,7 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
if (object->IsJSObject()) {
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
- bool key_is_smi_like = key->IsSmi() || !key->ToSmi()->IsFailure();
+ bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null();
if (receiver->elements()->map() ==
isolate()->heap()->sloppy_arguments_elements_map()) {
if (strict_mode() == SLOPPY) {
@@ -1735,13 +1803,56 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
TRACE_IC("StoreIC", key);
}
- if (maybe_object) return maybe_object;
- Handle<Object> result = Runtime::SetObjectProperty(isolate(), object, key,
- value,
- NONE,
- strict_mode());
- RETURN_IF_EMPTY_HANDLE(isolate(), result);
- return *result;
+ if (!store_handle.is_null()) return store_handle;
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate(),
+ result,
+ Runtime::SetObjectProperty(
+ isolate(), object, key, value, NONE, strict_mode()),
+ Object);
+ return result;
+}
+
+
+CallIC::State::State(ExtraICState extra_ic_state)
+ : argc_(ArgcBits::decode(extra_ic_state)),
+ call_type_(CallTypeBits::decode(extra_ic_state)) {
+}
+
+
+ExtraICState CallIC::State::GetExtraICState() const {
+ ExtraICState extra_ic_state =
+ ArgcBits::encode(argc_) |
+ CallTypeBits::encode(call_type_);
+ return extra_ic_state;
+}
+
+
+void CallIC::HandleMiss(Handle<Object> receiver,
+ Handle<Object> function,
+ Handle<FixedArray> vector,
+ Handle<Smi> slot) {
+ State state(target()->extra_ic_state());
+ Object* feedback = vector->get(slot->value());
+
+ if (feedback->IsJSFunction() || !function->IsJSFunction()) {
+ // We are going generic.
+ ASSERT(!function->IsJSFunction() || *function != feedback);
+
+ vector->set(slot->value(),
+ *TypeFeedbackInfo::MegamorphicSentinel(isolate()),
+ SKIP_WRITE_BARRIER);
+ TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic");
+ } else {
+ // If we came here feedback must be the uninitialized sentinel,
+ // and we are going monomorphic.
+ ASSERT(feedback == *TypeFeedbackInfo::UninitializedSentinel(isolate()));
+ Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
+ Handle<Object> name(js_function->shared()->name(), isolate());
+ TRACE_IC("CallIC", name);
+ vector->set(slot->value(), *function);
+ }
}
@@ -1753,65 +1864,94 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
//
// Used from ic-<arch>.cc.
+RUNTIME_FUNCTION(CallIC_Miss) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 4);
+ CallIC ic(isolate);
+ Handle<Object> receiver = args.at<Object>(0);
+ Handle<Object> function = args.at<Object>(1);
+ Handle<FixedArray> vector = args.at<FixedArray>(2);
+ Handle<Smi> slot = args.at<Smi>(3);
+ ic.HandleMiss(receiver, function, vector, slot);
+ return *function;
+}
+
+
// Used from ic-<arch>.cc.
-RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) {
+RUNTIME_FUNCTION(LoadIC_Miss) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
Handle<Object> receiver = args.at<Object>(0);
Handle<String> key = args.at<String>(1);
ic.UpdateState(receiver, key);
- return ic.Load(receiver, key);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
+ return *result;
}
// Used from ic-<arch>.cc
-RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) {
+RUNTIME_FUNCTION(KeyedLoadIC_Miss) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate);
Handle<Object> receiver = args.at<Object>(0);
Handle<Object> key = args.at<Object>(1);
ic.UpdateState(receiver, key);
- return ic.Load(receiver, key);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure) {
+RUNTIME_FUNCTION(KeyedLoadIC_MissFromStubFailure) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate);
Handle<Object> receiver = args.at<Object>(0);
Handle<Object> key = args.at<Object>(1);
ic.UpdateState(receiver, key);
- return ic.Load(receiver, key);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
+ return *result;
}
// Used from ic-<arch>.cc.
-RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) {
+RUNTIME_FUNCTION(StoreIC_Miss) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
Handle<Object> receiver = args.at<Object>(0);
Handle<String> key = args.at<String>(1);
ic.UpdateState(receiver, key);
- return ic.Store(receiver, key, args.at<Object>(2));
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ result,
+ ic.Store(receiver, key, args.at<Object>(2)));
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) {
+RUNTIME_FUNCTION(StoreIC_MissFromStubFailure) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
StoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
Handle<Object> receiver = args.at<Object>(0);
Handle<String> key = args.at<String>(1);
ic.UpdateState(receiver, key);
- return ic.Store(receiver, key, args.at<Object>(2));
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ result,
+ ic.Store(receiver, key, args.at<Object>(2)));
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) {
+RUNTIME_FUNCTION(StoreIC_ArrayLength) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -1824,12 +1964,12 @@ RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) {
#ifdef DEBUG
// The length property has to be a writable callback property.
LookupResult debug_lookup(isolate);
- receiver->LocalLookup(isolate->heap()->length_string(), &debug_lookup);
+ receiver->LocalLookup(isolate->factory()->length_string(), &debug_lookup);
ASSERT(debug_lookup.IsPropertyCallbacks() && !debug_lookup.IsReadOnly());
#endif
- RETURN_IF_EMPTY_HANDLE(isolate,
- JSArray::SetElementsLength(receiver, len));
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, JSArray::SetElementsLength(receiver, len));
return *len;
}
@@ -1837,74 +1977,79 @@ RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) {
// Extend storage is called in a store inline cache when
// it is necessary to extend the properties array of a
// JSObject.
-RUNTIME_FUNCTION(MaybeObject*, SharedStoreIC_ExtendStorage) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(SharedStoreIC_ExtendStorage) {
+ HandleScope shs(isolate);
ASSERT(args.length() == 3);
// Convert the parameters
- JSObject* object = JSObject::cast(args[0]);
- Map* transition = Map::cast(args[1]);
- Object* value = args[2];
+ Handle<JSObject> object = args.at<JSObject>(0);
+ Handle<Map> transition = args.at<Map>(1);
+ Handle<Object> value = args.at<Object>(2);
// Check the object has run out out property space.
ASSERT(object->HasFastProperties());
ASSERT(object->map()->unused_property_fields() == 0);
// Expand the properties array.
- FixedArray* old_storage = object->properties();
+ Handle<FixedArray> old_storage = handle(object->properties(), isolate);
int new_unused = transition->unused_property_fields();
int new_size = old_storage->length() + new_unused + 1;
- Object* result;
- MaybeObject* maybe_result = old_storage->CopySize(new_size);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- FixedArray* new_storage = FixedArray::cast(result);
+ Handle<FixedArray> new_storage = FixedArray::CopySize(old_storage, new_size);
- Object* to_store = value;
+ Handle<Object> to_store = value;
- DescriptorArray* descriptors = transition->instance_descriptors();
- PropertyDetails details = descriptors->GetDetails(transition->LastAdded());
+ PropertyDetails details = transition->instance_descriptors()->GetDetails(
+ transition->LastAdded());
if (details.representation().IsDouble()) {
- MaybeObject* maybe_storage =
- isolate->heap()->AllocateHeapNumber(value->Number());
- if (!maybe_storage->To(&to_store)) return maybe_storage;
+ to_store = isolate->factory()->NewHeapNumber(value->Number());
}
- new_storage->set(old_storage->length(), to_store);
+ new_storage->set(old_storage->length(), *to_store);
// Set the new property value and do the map transition.
- object->set_properties(new_storage);
- object->set_map(transition);
+ object->set_properties(*new_storage);
+ object->set_map(*transition);
// Return the stored value.
- return value;
+ return *value;
}
// Used from ic-<arch>.cc.
-RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) {
+RUNTIME_FUNCTION(KeyedStoreIC_Miss) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
Handle<Object> receiver = args.at<Object>(0);
Handle<Object> key = args.at<Object>(1);
ic.UpdateState(receiver, key);
- return ic.Store(receiver, key, args.at<Object>(2));
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ result,
+ ic.Store(receiver, key, args.at<Object>(2)));
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure) {
+RUNTIME_FUNCTION(KeyedStoreIC_MissFromStubFailure) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
Handle<Object> receiver = args.at<Object>(0);
Handle<Object> key = args.at<Object>(1);
ic.UpdateState(receiver, key);
- return ic.Store(receiver, key, args.at<Object>(2));
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ result,
+ ic.Store(receiver, key, args.at<Object>(2)));
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) {
+RUNTIME_FUNCTION(StoreIC_Slow) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
@@ -1912,16 +2057,16 @@ RUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) {
Handle<Object> key = args.at<Object>(1);
Handle<Object> value = args.at<Object>(2);
StrictMode strict_mode = ic.strict_mode();
- Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key,
- value,
- NONE,
- strict_mode);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Runtime::SetObjectProperty(
+ isolate, object, key, value, NONE, strict_mode));
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) {
+RUNTIME_FUNCTION(KeyedStoreIC_Slow) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
@@ -1929,16 +2074,16 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) {
Handle<Object> key = args.at<Object>(1);
Handle<Object> value = args.at<Object>(2);
StrictMode strict_mode = ic.strict_mode();
- Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key,
- value,
- NONE,
- strict_mode);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Runtime::SetObjectProperty(
+ isolate, object, key, value, NONE, strict_mode));
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss) {
+RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
@@ -1951,16 +2096,17 @@ RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss) {
JSObject::TransitionElementsKind(Handle<JSObject>::cast(object),
map->elements_kind());
}
- Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key,
- value,
- NONE,
- strict_mode);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Runtime::SetObjectProperty(
+ isolate, object, key, value, NONE, strict_mode));
return *result;
}
-BinaryOpIC::State::State(ExtraICState extra_ic_state) {
+BinaryOpIC::State::State(Isolate* isolate, ExtraICState extra_ic_state)
+ : isolate_(isolate) {
// We don't deserialize the SSE2 Field, since this is only used to be able
// to include SSE2 as well as non-SSE2 versions in the snapshot. For code
// generation we always want it to reflect the current state.
@@ -1984,7 +2130,7 @@ BinaryOpIC::State::State(ExtraICState extra_ic_state) {
ExtraICState BinaryOpIC::State::GetExtraICState() const {
bool sse2 = (Max(result_kind_, Max(left_kind_, right_kind_)) > SMI &&
- CpuFeatures::IsSafeForSnapshot(SSE2));
+ CpuFeatures::IsSafeForSnapshot(isolate(), SSE2));
ExtraICState extra_ic_state =
SSE2Field::encode(sse2) |
OpField::encode(op_ - FIRST_TOKEN) |
@@ -2011,7 +2157,7 @@ void BinaryOpIC::State::GenerateAheadOfTime(
// Generated list of commonly used stubs
#define GENERATE(op, left_kind, right_kind, result_kind, mode) \
do { \
- State state(op, mode); \
+ State state(isolate, op, mode); \
state.left_kind_ = left_kind; \
state.fixed_right_arg_.has_value = false; \
state.right_kind_ = right_kind; \
@@ -2206,7 +2352,7 @@ void BinaryOpIC::State::GenerateAheadOfTime(
#undef GENERATE
#define GENERATE(op, left_kind, fixed_right_arg_value, result_kind, mode) \
do { \
- State state(op, mode); \
+ State state(isolate, op, mode); \
state.left_kind_ = left_kind; \
state.fixed_right_arg_.has_value = true; \
state.fixed_right_arg_.value = fixed_right_arg_value; \
@@ -2380,25 +2526,28 @@ Type* BinaryOpIC::State::KindToType(Kind kind, Zone* zone) {
}
-MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site,
- Handle<Object> left,
- Handle<Object> right) {
- State state(target()->extra_ic_state());
+MaybeHandle<Object> BinaryOpIC::Transition(
+ Handle<AllocationSite> allocation_site,
+ Handle<Object> left,
+ Handle<Object> right) {
+ State state(isolate(), target()->extra_ic_state());
// Compute the actual result using the builtin for the binary operation.
Object* builtin = isolate()->js_builtins_object()->javascript_builtin(
TokenToJSBuiltin(state.op()));
Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate());
- bool caught_exception;
- Handle<Object> result = Execution::Call(
- isolate(), function, left, 1, &right, &caught_exception);
- if (caught_exception) return Failure::Exception();
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate(),
+ result,
+ Execution::Call(isolate(), function, left, 1, &right),
+ Object);
// Execution::Call can execute arbitrary JavaScript, hence potentially
// update the state of this very IC, so we must update the stored state.
UpdateTarget();
// Compute the new state.
- State old_state(target()->extra_ic_state());
+ State old_state(isolate(), target()->extra_ic_state());
state.Update(left, right, result);
// Check if we have a string operation here.
@@ -2410,15 +2559,15 @@ MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site,
}
// Install the stub with an allocation site.
- BinaryOpICWithAllocationSiteStub stub(state);
- target = stub.GetCodeCopyFromTemplate(isolate(), allocation_site);
+ BinaryOpICWithAllocationSiteStub stub(isolate(), state);
+ target = stub.GetCodeCopyFromTemplate(allocation_site);
// Sanity check the trampoline stub.
ASSERT_EQ(*allocation_site, target->FindFirstAllocationSite());
} else {
// Install the generic stub.
- BinaryOpICStub stub(state);
- target = stub.GetCode(isolate());
+ BinaryOpICStub stub(isolate(), state);
+ target = stub.GetCode();
// Sanity check the generic stub.
ASSERT_EQ(NULL, target->FindFirstAllocationSite());
@@ -2450,21 +2599,26 @@ MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site,
PatchInlinedSmiCode(address(), DISABLE_INLINED_SMI_CHECK);
}
- return *result;
+ return result;
}
-RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss) {
+RUNTIME_FUNCTION(BinaryOpIC_Miss) {
HandleScope scope(isolate);
ASSERT_EQ(2, args.length());
Handle<Object> left = args.at<Object>(BinaryOpICStub::kLeft);
Handle<Object> right = args.at<Object>(BinaryOpICStub::kRight);
BinaryOpIC ic(isolate);
- return ic.Transition(Handle<AllocationSite>::null(), left, right);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ result,
+ ic.Transition(Handle<AllocationSite>::null(), left, right));
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_MissWithAllocationSite) {
+RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite) {
HandleScope scope(isolate);
ASSERT_EQ(3, args.length());
Handle<AllocationSite> allocation_site = args.at<AllocationSite>(
@@ -2474,21 +2628,26 @@ RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_MissWithAllocationSite) {
Handle<Object> right = args.at<Object>(
BinaryOpWithAllocationSiteStub::kRight);
BinaryOpIC ic(isolate);
- return ic.Transition(allocation_site, left, right);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ result,
+ ic.Transition(allocation_site, left, right));
+ return *result;
}
Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) {
- ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED);
+ ICCompareStub stub(isolate, op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED);
Code* code = NULL;
- CHECK(stub.FindCodeInCache(&code, isolate));
+ CHECK(stub.FindCodeInCache(&code));
return code;
}
Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op) {
- ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED);
- return stub.GetCode(isolate);
+ ICCompareStub stub(isolate, op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED);
+ return stub.GetCode();
}
@@ -2660,12 +2819,12 @@ Code* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
State new_right = NewInputState(previous_right, y);
State state = TargetState(previous_state, previous_left, previous_right,
HasInlinedSmiCode(address()), x, y);
- ICCompareStub stub(op_, new_left, new_right, state);
+ ICCompareStub stub(isolate(), op_, new_left, new_right, state);
if (state == KNOWN_OBJECT) {
stub.set_known_map(
Handle<Map>(Handle<JSObject>::cast(x)->map(), isolate()));
}
- Handle<Code> new_target = stub.GetCode(isolate());
+ Handle<Code> new_target = stub.GetCode();
set_target(*new_target);
if (FLAG_trace_ic) {
@@ -2679,7 +2838,7 @@ Code* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
GetStateName(new_right),
GetStateName(state),
Token::Name(op_),
- static_cast<void*>(*stub.GetCode(isolate())));
+ static_cast<void*>(*stub.GetCode()));
}
// Activate inlined smi code.
@@ -2692,7 +2851,7 @@ Code* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
// Used from ICCompareStub::GenerateMiss in code-stubs-<arch>.cc.
-RUNTIME_FUNCTION(Code*, CompareIC_Miss) {
+RUNTIME_FUNCTION(CompareIC_Miss) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2)));
@@ -2706,29 +2865,32 @@ void CompareNilIC::Clear(Address address,
if (IsCleared(target)) return;
ExtraICState state = target->extra_ic_state();
- CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED);
+ CompareNilICStub stub(target->GetIsolate(),
+ state,
+ HydrogenCodeStub::UNINITIALIZED);
stub.ClearState();
Code* code = NULL;
- CHECK(stub.FindCodeInCache(&code, target->GetIsolate()));
+ CHECK(stub.FindCodeInCache(&code));
SetTargetAtAddress(address, code, constant_pool);
}
-MaybeObject* CompareNilIC::DoCompareNilSlow(NilValue nil,
- Handle<Object> object) {
+Handle<Object> CompareNilIC::DoCompareNilSlow(Isolate* isolate,
+ NilValue nil,
+ Handle<Object> object) {
if (object->IsNull() || object->IsUndefined()) {
- return Smi::FromInt(true);
+ return handle(Smi::FromInt(true), isolate);
}
- return Smi::FromInt(object->IsUndetectableObject());
+ return handle(Smi::FromInt(object->IsUndetectableObject()), isolate);
}
-MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) {
+Handle<Object> CompareNilIC::CompareNil(Handle<Object> object) {
ExtraICState extra_ic_state = target()->extra_ic_state();
- CompareNilICStub stub(extra_ic_state);
+ CompareNilICStub stub(isolate(), extra_ic_state);
// Extract the current supported types from the patched IC and calculate what
// types must be supported as a result of the miss.
@@ -2741,27 +2903,27 @@ MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) {
// Find or create the specialized stub to support the new set of types.
Handle<Code> code;
if (stub.IsMonomorphic()) {
- Handle<Map> monomorphic_map(already_monomorphic
- ? target()->FindFirstMap()
+ Handle<Map> monomorphic_map(already_monomorphic && FirstTargetMap() != NULL
+ ? FirstTargetMap()
: HeapObject::cast(*object)->map());
code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub);
} else {
- code = stub.GetCode(isolate());
+ code = stub.GetCode();
}
set_target(*code);
- return DoCompareNilSlow(nil, object);
+ return DoCompareNilSlow(isolate(), nil, object);
}
-RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss) {
+RUNTIME_FUNCTION(CompareNilIC_Miss) {
HandleScope scope(isolate);
Handle<Object> object = args.at<Object>(0);
CompareNilIC ic(isolate);
- return ic.CompareNil(object);
+ return *ic.CompareNil(object);
}
-RUNTIME_FUNCTION(MaybeObject*, Unreachable) {
+RUNTIME_FUNCTION(Unreachable) {
UNREACHABLE();
CHECK(false);
return isolate->heap()->undefined_value();
@@ -2809,21 +2971,21 @@ Builtins::JavaScript BinaryOpIC::TokenToJSBuiltin(Token::Value op) {
}
-MaybeObject* ToBooleanIC::ToBoolean(Handle<Object> object) {
- ToBooleanStub stub(target()->extra_ic_state());
+Handle<Object> ToBooleanIC::ToBoolean(Handle<Object> object) {
+ ToBooleanStub stub(isolate(), target()->extra_ic_state());
bool to_boolean_value = stub.UpdateStatus(object);
- Handle<Code> code = stub.GetCode(isolate());
+ Handle<Code> code = stub.GetCode();
set_target(*code);
- return Smi::FromInt(to_boolean_value ? 1 : 0);
+ return handle(Smi::FromInt(to_boolean_value ? 1 : 0), isolate());
}
-RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss) {
+RUNTIME_FUNCTION(ToBooleanIC_Miss) {
ASSERT(args.length() == 1);
HandleScope scope(isolate);
Handle<Object> object = args.at<Object>(0);
ToBooleanIC ic(isolate);
- return ic.ToBoolean(object);
+ return *ic.ToBoolean(object);
}
diff --git a/deps/v8/src/ic.h b/deps/v8/src/ic.h
index e70cb82c96..895c21e736 100644
--- a/deps/v8/src/ic.h
+++ b/deps/v8/src/ic.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_IC_H_
#define V8_IC_H_
@@ -42,6 +19,7 @@ const int kMaxKeyedPolymorphism = 4;
#define IC_UTIL_LIST(ICU) \
ICU(LoadIC_Miss) \
ICU(KeyedLoadIC_Miss) \
+ ICU(CallIC_Miss) \
ICU(StoreIC_Miss) \
ICU(StoreIC_ArrayLength) \
ICU(StoreIC_Slow) \
@@ -96,10 +74,24 @@ class IC {
// Compute the current IC state based on the target stub, receiver and name.
void UpdateState(Handle<Object> receiver, Handle<Object> name);
- void MarkMonomorphicPrototypeFailure() {
- state_ = MONOMORPHIC_PROTOTYPE_FAILURE;
+
+ bool IsNameCompatibleWithMonomorphicPrototypeFailure(Handle<Object> name);
+ bool TryMarkMonomorphicPrototypeFailure(Handle<Object> name) {
+ if (IsNameCompatibleWithMonomorphicPrototypeFailure(name)) {
+ state_ = MONOMORPHIC_PROTOTYPE_FAILURE;
+ return true;
+ }
+ return false;
}
+ // If the stub contains weak maps then this function adds the stub to
+ // the dependent code array of each weak map.
+ static void RegisterWeakMapDependency(Handle<Code> stub);
+
+ // This function is called when a weak map in the stub is dying,
+ // invalidates the stub by setting maps in it to undefined.
+ static void InvalidateMaps(Code* stub);
+
// Clear the inline cache to initial state.
static void Clear(Isolate* isolate,
Address address,
@@ -113,6 +105,10 @@ class IC {
bool IsStoreStub() const {
return target()->is_store_stub() || target()->is_keyed_store_stub();
}
+
+ bool IsCallStub() const {
+ return target()->is_call_stub();
+ }
#endif
// Determines which map must be used for keeping the code stub.
@@ -156,17 +152,18 @@ class IC {
Address pc() const { return *pc_address_; }
Isolate* isolate() const { return isolate_; }
-#ifdef ENABLE_DEBUGGER_SUPPORT
// Get the shared function info of the caller.
SharedFunctionInfo* GetSharedFunctionInfo() const;
// Get the code object of the caller.
Code* GetCode() const;
// Get the original (non-breakpointed) code object of the caller.
Code* GetOriginalCode() const;
-#endif
// Set the call-site target.
void set_target(Code* code) {
+#ifdef VERIFY_HEAP
+ code->VerifyEmbeddedObjectsDependency();
+#endif
SetTargetAtAddress(address(), code, constant_pool());
target_set_ = true;
}
@@ -179,10 +176,10 @@ class IC {
void TraceIC(const char* type, Handle<Object> name);
#endif
- Failure* TypeError(const char* type,
- Handle<Object> object,
- Handle<Object> key);
- Failure* ReferenceError(const char* type, Handle<String> name);
+ MaybeHandle<Object> TypeError(const char* type,
+ Handle<Object> object,
+ Handle<Object> key);
+ MaybeHandle<Object> ReferenceError(const char* type, Handle<String> name);
// Access the target code for the given IC address.
static inline Code* GetTargetAtAddress(Address address,
@@ -247,6 +244,25 @@ class IC {
extra_ic_state_ = state;
}
+ void TargetMaps(MapHandleList* list) {
+ FindTargetMaps();
+ for (int i = 0; i < target_maps_.length(); i++) {
+ list->Add(target_maps_.at(i));
+ }
+ }
+
+ void TargetTypes(TypeHandleList* list) {
+ FindTargetMaps();
+ for (int i = 0; i < target_maps_.length(); i++) {
+ list->Add(IC::MapToType<HeapType>(target_maps_.at(i), isolate_));
+ }
+ }
+
+ Map* FirstTargetMap() {
+ FindTargetMaps();
+ return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL;
+ }
+
protected:
void UpdateTarget() {
target_ = handle(raw_target(), isolate_);
@@ -259,6 +275,17 @@ class IC {
inline ConstantPoolArray* constant_pool() const;
inline ConstantPoolArray* raw_constant_pool() const;
+ void FindTargetMaps() {
+ if (target_maps_set_) return;
+ target_maps_set_ = true;
+ if (state_ == MONOMORPHIC) {
+ Map* map = target_->FindFirstMap();
+ if (map != NULL) target_maps_.Add(handle(map));
+ } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) {
+ target_->FindAllMaps(&target_maps_);
+ }
+ }
+
// Frame pointer for the frame that uses (calls) the IC.
Address fp_;
@@ -280,6 +307,8 @@ class IC {
bool target_set_;
ExtraICState extra_ic_state_;
+ MapHandleList target_maps_;
+ bool target_maps_set_;
DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
};
@@ -301,6 +330,78 @@ class IC_Utility {
};
+class CallIC: public IC {
+ public:
+ enum CallType { METHOD, FUNCTION };
+
+ class State V8_FINAL BASE_EMBEDDED {
+ public:
+ explicit State(ExtraICState extra_ic_state);
+
+ static State DefaultCallState(int argc, CallType call_type) {
+ return State(argc, call_type);
+ }
+
+ static State MegamorphicCallState(int argc, CallType call_type) {
+ return State(argc, call_type);
+ }
+
+ InlineCacheState GetICState() const { return ::v8::internal::GENERIC; }
+
+ ExtraICState GetExtraICState() const;
+
+ static void GenerateAheadOfTime(
+ Isolate*, void (*Generate)(Isolate*, const State&));
+
+ int arg_count() const { return argc_; }
+ CallType call_type() const { return call_type_; }
+
+ bool CallAsMethod() const { return call_type_ == METHOD; }
+
+ void Print(StringStream* stream) const;
+
+ bool operator==(const State& other_state) const {
+ return (argc_ == other_state.argc_ &&
+ call_type_ == other_state.call_type_);
+ }
+
+ bool operator!=(const State& other_state) const {
+ return !(*this == other_state);
+ }
+
+ private:
+ State(int argc,
+ CallType call_type)
+ : argc_(argc),
+ call_type_(call_type) {
+ }
+
+ class ArgcBits: public BitField<int, 0, Code::kArgumentsBits> {};
+ class CallTypeBits: public BitField<CallType, Code::kArgumentsBits, 1> {};
+
+ const int argc_;
+ const CallType call_type_;
+ };
+
+ explicit CallIC(Isolate* isolate)
+ : IC(EXTRA_CALL_FRAME, isolate) {
+ }
+
+ void HandleMiss(Handle<Object> receiver,
+ Handle<Object> function,
+ Handle<FixedArray> vector,
+ Handle<Smi> slot);
+
+ // Code generator routines.
+ static Handle<Code> initialize_stub(Isolate* isolate,
+ int argc,
+ CallType call_type);
+
+ static void Clear(Isolate* isolate, Address address, Code* target,
+ ConstantPoolArray* constant_pool);
+};
+
+
class LoadIC: public IC {
public:
// ExtraICState bits
@@ -348,8 +449,8 @@ class LoadIC: public IC {
static Handle<Code> initialize_stub(Isolate* isolate,
ExtraICState extra_state);
- MUST_USE_RESULT MaybeObject* Load(Handle<Object> object,
- Handle<String> name);
+ MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
+ Handle<String> name);
protected:
virtual Code::Kind kind() const { return Code::LOAD_IC; }
@@ -410,8 +511,8 @@ class KeyedLoadIC: public LoadIC {
ASSERT(target()->is_keyed_load_stub());
}
- MUST_USE_RESULT MaybeObject* Load(Handle<Object> object,
- Handle<Object> key);
+ MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
+ Handle<Object> key);
// Code generator routines.
static void GenerateMiss(MacroAssembler* masm);
@@ -515,7 +616,7 @@ class StoreIC: public IC {
static Handle<Code> initialize_stub(Isolate* isolate,
StrictMode strict_mode);
- MUST_USE_RESULT MaybeObject* Store(
+ MUST_USE_RESULT MaybeHandle<Object> Store(
Handle<Object> object,
Handle<String> name,
Handle<Object> value,
@@ -604,9 +705,9 @@ class KeyedStoreIC: public StoreIC {
ASSERT(target()->is_keyed_store_stub());
}
- MUST_USE_RESULT MaybeObject* Store(Handle<Object> object,
- Handle<Object> name,
- Handle<Object> value);
+ MUST_USE_RESULT MaybeHandle<Object> Store(Handle<Object> object,
+ Handle<Object> name,
+ Handle<Object> value);
// Code generators for stub routines. Only called once at startup.
static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
@@ -679,7 +780,7 @@ class KeyedStoreIC: public StoreIC {
Handle<Object> key,
Handle<Object> value);
- Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver,
+ Handle<Map> ComputeTransitionedMap(Handle<Map> map,
KeyedAccessStoreMode store_mode);
friend class IC;
@@ -694,11 +795,11 @@ class BinaryOpIC: public IC {
public:
class State V8_FINAL BASE_EMBEDDED {
public:
- explicit State(ExtraICState extra_ic_state);
+ State(Isolate* isolate, ExtraICState extra_ic_state);
- State(Token::Value op, OverwriteMode mode)
+ State(Isolate* isolate, Token::Value op, OverwriteMode mode)
: op_(op), mode_(mode), left_kind_(NONE), right_kind_(NONE),
- result_kind_(NONE) {
+ result_kind_(NONE), isolate_(isolate) {
ASSERT_LE(FIRST_TOKEN, op);
ASSERT_LE(op, LAST_TOKEN);
}
@@ -775,6 +876,8 @@ class BinaryOpIC: public IC {
Handle<Object> right,
Handle<Object> result);
+ Isolate* isolate() const { return isolate_; }
+
private:
enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
@@ -805,15 +908,16 @@ class BinaryOpIC: public IC {
Kind right_kind_;
Kind result_kind_;
Maybe<int> fixed_right_arg_;
+ Isolate* isolate_;
};
explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) { }
static Builtins::JavaScript TokenToJSBuiltin(Token::Value op);
- MaybeObject* Transition(Handle<AllocationSite> allocation_site,
- Handle<Object> left,
- Handle<Object> right) V8_WARN_UNUSED_RESULT;
+ MaybeHandle<Object> Transition(Handle<AllocationSite> allocation_site,
+ Handle<Object> left,
+ Handle<Object> right) V8_WARN_UNUSED_RESULT;
};
@@ -895,7 +999,7 @@ class CompareNilIC: public IC {
public:
explicit CompareNilIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
- MUST_USE_RESULT MaybeObject* CompareNil(Handle<Object> object);
+ Handle<Object> CompareNil(Handle<Object> object);
static Handle<Code> GetUninitialized();
@@ -903,8 +1007,8 @@ class CompareNilIC: public IC {
Code* target,
ConstantPoolArray* constant_pool);
- static MUST_USE_RESULT MaybeObject* DoCompareNilSlow(NilValue nil,
- Handle<Object> object);
+ static Handle<Object> DoCompareNilSlow(Isolate* isolate, NilValue nil,
+ Handle<Object> object);
};
@@ -912,7 +1016,7 @@ class ToBooleanIC: public IC {
public:
explicit ToBooleanIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) { }
- MaybeObject* ToBoolean(Handle<Object> object);
+ Handle<Object> ToBoolean(Handle<Object> object);
};
@@ -920,15 +1024,15 @@ class ToBooleanIC: public IC {
enum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK };
void PatchInlinedSmiCode(Address address, InlinedSmiCheck check);
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure);
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure);
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, UnaryOpIC_Miss);
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure);
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss);
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss);
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_MissWithAllocationSite);
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss);
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss);
+DECLARE_RUNTIME_FUNCTION(KeyedLoadIC_MissFromStubFailure);
+DECLARE_RUNTIME_FUNCTION(KeyedStoreIC_MissFromStubFailure);
+DECLARE_RUNTIME_FUNCTION(UnaryOpIC_Miss);
+DECLARE_RUNTIME_FUNCTION(StoreIC_MissFromStubFailure);
+DECLARE_RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss);
+DECLARE_RUNTIME_FUNCTION(BinaryOpIC_Miss);
+DECLARE_RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite);
+DECLARE_RUNTIME_FUNCTION(CompareNilIC_Miss);
+DECLARE_RUNTIME_FUNCTION(ToBooleanIC_Miss);
} } // namespace v8::internal
diff --git a/deps/v8/src/icu_util.cc b/deps/v8/src/icu_util.cc
index 1fff8170ff..b036ef4eef 100644
--- a/deps/v8/src/icu_util.cc
+++ b/deps/v8/src/icu_util.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "icu_util.h"
diff --git a/deps/v8/src/icu_util.h b/deps/v8/src/icu_util.h
index 6b50c185c5..cd98ff0dfc 100644
--- a/deps/v8/src/icu_util.h
+++ b/deps/v8/src/icu_util.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ICU_UTIL_H_
diff --git a/deps/v8/src/incremental-marking-inl.h b/deps/v8/src/incremental-marking-inl.h
index 1c30383d52..19d471c367 100644
--- a/deps/v8/src/incremental-marking-inl.h
+++ b/deps/v8/src/incremental-marking-inl.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_INCREMENTAL_MARKING_INL_H_
#define V8_INCREMENTAL_MARKING_INL_H_
@@ -68,7 +45,7 @@ bool IncrementalMarking::BaseRecordWrite(HeapObject* obj,
void IncrementalMarking::RecordWrite(HeapObject* obj,
Object** slot,
Object* value) {
- if (IsMarking() && value->NonFailureIsHeapObject()) {
+ if (IsMarking() && value->IsHeapObject()) {
RecordWriteSlow(obj, slot, value);
}
}
@@ -84,7 +61,7 @@ void IncrementalMarking::RecordWriteOfCodeEntry(JSFunction* host,
void IncrementalMarking::RecordWriteIntoCode(HeapObject* obj,
RelocInfo* rinfo,
Object* value) {
- if (IsMarking() && value->NonFailureIsHeapObject()) {
+ if (IsMarking() && value->IsHeapObject()) {
RecordWriteIntoCodeSlow(obj, rinfo, value);
}
}
diff --git a/deps/v8/src/incremental-marking.cc b/deps/v8/src/incremental-marking.cc
index bbe0c51a58..2b6765c72c 100644
--- a/deps/v8/src/incremental-marking.cc
+++ b/deps/v8/src/incremental-marking.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -31,9 +8,9 @@
#include "code-stubs.h"
#include "compilation-cache.h"
+#include "conversions.h"
#include "objects-visiting.h"
#include "objects-visiting-inl.h"
-#include "v8conversions.h"
namespace v8 {
namespace internal {
@@ -263,7 +240,7 @@ class IncrementalMarkingMarkingVisitor
INLINE(static void VisitPointer(Heap* heap, Object** p)) {
Object* obj = *p;
- if (obj->NonFailureIsHeapObject()) {
+ if (obj->IsHeapObject()) {
heap->mark_compact_collector()->RecordSlot(p, p, obj);
MarkObject(heap, obj);
}
@@ -272,7 +249,7 @@ class IncrementalMarkingMarkingVisitor
INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) {
for (Object** p = start; p < end; p++) {
Object* obj = *p;
- if (obj->NonFailureIsHeapObject()) {
+ if (obj->IsHeapObject()) {
heap->mark_compact_collector()->RecordSlot(start, p, obj);
MarkObject(heap, obj);
}
@@ -285,7 +262,7 @@ class IncrementalMarkingMarkingVisitor
Object** end)) {
for (Object** p = start; p < end; p++) {
Object* obj = *p;
- if (obj->NonFailureIsHeapObject()) {
+ if (obj->IsHeapObject()) {
heap->mark_compact_collector()->RecordSlot(anchor, p, obj);
MarkObject(heap, obj);
}
@@ -482,7 +459,7 @@ bool IncrementalMarking::WorthActivating() {
return FLAG_incremental_marking &&
FLAG_incremental_marking_steps &&
heap_->gc_state() == Heap::NOT_IN_GC &&
- !Serializer::enabled() &&
+ !Serializer::enabled(heap_->isolate()) &&
heap_->isolate()->IsInitialized() &&
heap_->PromotedSpaceSizeOfObjects() > kActivationThreshold;
}
@@ -560,12 +537,12 @@ void IncrementalMarking::Start(CompactionFlag flag) {
ASSERT(FLAG_incremental_marking_steps);
ASSERT(state_ == STOPPED);
ASSERT(heap_->gc_state() == Heap::NOT_IN_GC);
- ASSERT(!Serializer::enabled());
+ ASSERT(!Serializer::enabled(heap_->isolate()));
ASSERT(heap_->isolate()->IsInitialized());
ResetStepCounters();
- if (heap_->IsSweepingComplete()) {
+ if (!heap_->mark_compact_collector()->IsConcurrentSweepingInProgress()) {
StartMarking(flag);
} else {
if (FLAG_trace_incremental_marking) {
@@ -909,7 +886,11 @@ void IncrementalMarking::Step(intptr_t allocated_bytes,
}
if (state_ == SWEEPING) {
- if (heap_->EnsureSweepersProgressed(static_cast<int>(bytes_to_process))) {
+ if (heap_->mark_compact_collector()->IsConcurrentSweepingInProgress() &&
+ heap_->mark_compact_collector()->IsSweepingCompleted()) {
+ heap_->mark_compact_collector()->WaitUntilSweepingCompleted();
+ }
+ if (!heap_->mark_compact_collector()->IsConcurrentSweepingInProgress()) {
bytes_scanned_ = 0;
StartMarking(PREVENT_COMPACTION);
}
diff --git a/deps/v8/src/incremental-marking.h b/deps/v8/src/incremental-marking.h
index f4362ff5da..2ea30b17c2 100644
--- a/deps/v8/src/incremental-marking.h
+++ b/deps/v8/src/incremental-marking.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_INCREMENTAL_MARKING_H_
#define V8_INCREMENTAL_MARKING_H_
diff --git a/deps/v8/src/interface.cc b/deps/v8/src/interface.cc
index c39d50e358..bd50c61ea7 100644
--- a/deps/v8/src/interface.cc
+++ b/deps/v8/src/interface.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/interface.h b/deps/v8/src/interface.h
index f824a9a874..31a9fa0c4d 100644
--- a/deps/v8/src/interface.h
+++ b/deps/v8/src/interface.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_INTERFACE_H_
#define V8_INTERFACE_H_
diff --git a/deps/v8/src/interpreter-irregexp.cc b/deps/v8/src/interpreter-irregexp.cc
index de54d0c426..4c7c04c13c 100644
--- a/deps/v8/src/interpreter-irregexp.cc
+++ b/deps/v8/src/interpreter-irregexp.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// A simple interpreter for the Irregexp byte code.
diff --git a/deps/v8/src/interpreter-irregexp.h b/deps/v8/src/interpreter-irregexp.h
index 0f45d98207..4953a601e4 100644
--- a/deps/v8/src/interpreter-irregexp.h
+++ b/deps/v8/src/interpreter-irregexp.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// A simple interpreter for the Irregexp byte code.
diff --git a/deps/v8/src/isolate-inl.h b/deps/v8/src/isolate-inl.h
index 764bcb8bf3..eebdcee9bd 100644
--- a/deps/v8/src/isolate-inl.h
+++ b/deps/v8/src/isolate-inl.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ISOLATE_INL_H_
#define V8_ISOLATE_INL_H_
@@ -54,21 +31,12 @@ bool Isolate::IsCodePreAgingActive() {
bool Isolate::IsDebuggerActive() {
-#ifdef ENABLE_DEBUGGER_SUPPORT
- if (!NoBarrier_Load(&debugger_initialized_)) return false;
return debugger()->IsDebuggerActive();
-#else
- return false;
-#endif
}
bool Isolate::DebuggerHasBreakPoints() {
-#ifdef ENABLE_DEBUGGER_SUPPORT
return debug()->has_break_points();
-#else
- return false;
-#endif
}
diff --git a/deps/v8/src/isolate.cc b/deps/v8/src/isolate.cc
index 7e06a2ed5f..d93639b5d0 100644
--- a/deps/v8/src/isolate.cc
+++ b/deps/v8/src/isolate.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <stdlib.h>
@@ -156,8 +133,8 @@ Isolate::PerIsolateThreadData*
per_thread = new PerIsolateThreadData(this, thread_id);
thread_data_table_->Insert(per_thread);
}
+ ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread);
}
- ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread);
return per_thread;
}
@@ -212,37 +189,6 @@ struct StaticInitializer {
}
} static_initializer;
-#ifdef ENABLE_DEBUGGER_SUPPORT
-Debugger* Isolate::GetDefaultIsolateDebugger() {
- EnsureDefaultIsolate();
- return default_isolate_->debugger();
-}
-#endif
-
-
-StackGuard* Isolate::GetDefaultIsolateStackGuard() {
- EnsureDefaultIsolate();
- return default_isolate_->stack_guard();
-}
-
-
-void Isolate::EnterDefaultIsolate() {
- EnsureDefaultIsolate();
- ASSERT(default_isolate_ != NULL);
-
- PerIsolateThreadData* data = CurrentPerIsolateThreadData();
- // If not yet in default isolate - enter it.
- if (data == NULL || data->isolate() != default_isolate_) {
- default_isolate_->Enter();
- }
-}
-
-
-v8::Isolate* Isolate::GetDefaultIsolateForLocking() {
- EnsureDefaultIsolate();
- return reinterpret_cast<v8::Isolate*>(default_isolate_);
-}
-
Address Isolate::get_address_from_id(Isolate::AddressId id) {
return isolate_addresses_[id];
@@ -264,21 +210,11 @@ void Isolate::IterateThread(ThreadVisitor* v, char* t) {
void Isolate::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
// Visit the roots from the top for a given thread.
- Object* pending;
- // The pending exception can sometimes be a failure. We can't show
- // that to the GC, which only understands objects.
- if (thread->pending_exception_->ToObject(&pending)) {
- v->VisitPointer(&pending);
- thread->pending_exception_ = pending; // In case GC updated it.
- }
+ v->VisitPointer(&thread->pending_exception_);
v->VisitPointer(&(thread->pending_message_obj_));
v->VisitPointer(BitCast<Object**>(&(thread->pending_message_script_)));
v->VisitPointer(BitCast<Object**>(&(thread->context_)));
- Object* scheduled;
- if (thread->scheduled_exception_->ToObject(&scheduled)) {
- v->VisitPointer(&scheduled);
- thread->scheduled_exception_ = scheduled;
- }
+ v->VisitPointer(&thread->scheduled_exception_);
for (v8::TryCatch* block = thread->TryCatchHandler();
block != NULL;
@@ -560,7 +496,7 @@ Handle<JSArray> Isolate::CaptureCurrentStackTrace(
if (options & StackTrace::kLineNumber) {
int script_line_offset = script->line_offset()->value();
int position = frames[i].code()->SourcePosition(frames[i].pc());
- int line_number = GetScriptLineNumber(script, position);
+ int line_number = Script::GetLineNumber(script, position);
// line_number is already shifted by the script_line_offset.
int relative_line_number = line_number - script_line_offset;
if (options & StackTrace::kColumnOffset && relative_line_number >= 0) {
@@ -573,41 +509,31 @@ Handle<JSArray> Isolate::CaptureCurrentStackTrace(
// tag.
column_offset += script->column_offset()->value();
}
- CHECK_NOT_EMPTY_HANDLE(
- this,
- JSObject::SetLocalPropertyIgnoreAttributes(
- stack_frame, column_key,
- Handle<Smi>(Smi::FromInt(column_offset + 1), this), NONE));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ stack_frame, column_key,
+ Handle<Smi>(Smi::FromInt(column_offset + 1), this), NONE).Check();
}
- CHECK_NOT_EMPTY_HANDLE(
- this,
- JSObject::SetLocalPropertyIgnoreAttributes(
- stack_frame, line_key,
- Handle<Smi>(Smi::FromInt(line_number + 1), this), NONE));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ stack_frame, line_key,
+ Handle<Smi>(Smi::FromInt(line_number + 1), this), NONE).Check();
}
if (options & StackTrace::kScriptId) {
Handle<Smi> script_id(script->id(), this);
- CHECK_NOT_EMPTY_HANDLE(this,
- JSObject::SetLocalPropertyIgnoreAttributes(
- stack_frame, script_id_key, script_id,
- NONE));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ stack_frame, script_id_key, script_id, NONE).Check();
}
if (options & StackTrace::kScriptName) {
Handle<Object> script_name(script->name(), this);
- CHECK_NOT_EMPTY_HANDLE(this,
- JSObject::SetLocalPropertyIgnoreAttributes(
- stack_frame, script_name_key, script_name,
- NONE));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ stack_frame, script_name_key, script_name, NONE).Check();
}
if (options & StackTrace::kScriptNameOrSourceURL) {
- Handle<Object> result = GetScriptNameOrSourceURL(script);
- CHECK_NOT_EMPTY_HANDLE(this,
- JSObject::SetLocalPropertyIgnoreAttributes(
- stack_frame, script_name_or_source_url_key,
- result, NONE));
+ Handle<Object> result = Script::GetNameOrSourceURL(script);
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ stack_frame, script_name_or_source_url_key, result, NONE).Check();
}
if (options & StackTrace::kFunctionName) {
@@ -615,27 +541,23 @@ Handle<JSArray> Isolate::CaptureCurrentStackTrace(
if (!fun_name->BooleanValue()) {
fun_name = Handle<Object>(fun->shared()->inferred_name(), this);
}
- CHECK_NOT_EMPTY_HANDLE(this,
- JSObject::SetLocalPropertyIgnoreAttributes(
- stack_frame, function_key, fun_name, NONE));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ stack_frame, function_key, fun_name, NONE).Check();
}
if (options & StackTrace::kIsEval) {
Handle<Object> is_eval =
script->compilation_type() == Script::COMPILATION_TYPE_EVAL ?
factory()->true_value() : factory()->false_value();
- CHECK_NOT_EMPTY_HANDLE(this,
- JSObject::SetLocalPropertyIgnoreAttributes(
- stack_frame, eval_key, is_eval, NONE));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ stack_frame, eval_key, is_eval, NONE).Check();
}
if (options & StackTrace::kIsConstructor) {
Handle<Object> is_constructor = (frames[i].is_constructor()) ?
factory()->true_value() : factory()->false_value();
- CHECK_NOT_EMPTY_HANDLE(this,
- JSObject::SetLocalPropertyIgnoreAttributes(
- stack_frame, constructor_key,
- is_constructor, NONE));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ stack_frame, constructor_key, is_constructor, NONE).Check();
}
FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame);
@@ -717,28 +639,41 @@ void Isolate::SetFailedAccessCheckCallback(
}
-void Isolate::ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type) {
+static inline AccessCheckInfo* GetAccessCheckInfo(Isolate* isolate,
+ Handle<JSObject> receiver) {
+ JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
+ if (!constructor->shared()->IsApiFunction()) return NULL;
+
+ Object* data_obj =
+ constructor->shared()->get_api_func_data()->access_check_info();
+ if (data_obj == isolate->heap()->undefined_value()) return NULL;
+
+ return AccessCheckInfo::cast(data_obj);
+}
+
+
+void Isolate::ReportFailedAccessCheck(Handle<JSObject> receiver,
+ v8::AccessType type) {
if (!thread_local_top()->failed_access_check_callback_) return;
ASSERT(receiver->IsAccessCheckNeeded());
ASSERT(context());
// Get the data object from access check info.
- JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
- if (!constructor->shared()->IsApiFunction()) return;
- Object* data_obj =
- constructor->shared()->get_api_func_data()->access_check_info();
- if (data_obj == heap_.undefined_value()) return;
-
HandleScope scope(this);
- Handle<JSObject> receiver_handle(receiver);
- Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
- { VMState<EXTERNAL> state(this);
- thread_local_top()->failed_access_check_callback_(
- v8::Utils::ToLocal(receiver_handle),
+ Handle<Object> data;
+ { DisallowHeapAllocation no_gc;
+ AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver);
+ if (!access_check_info) return;
+ data = handle(access_check_info->data(), this);
+ }
+
+ // Leaving JavaScript.
+ VMState<EXTERNAL> state(this);
+ thread_local_top()->failed_access_check_callback_(
+ v8::Utils::ToLocal(receiver),
type,
v8::Utils::ToLocal(data));
- }
}
@@ -748,13 +683,14 @@ enum MayAccessDecision {
static MayAccessDecision MayAccessPreCheck(Isolate* isolate,
- JSObject* receiver,
+ Handle<JSObject> receiver,
v8::AccessType type) {
+ DisallowHeapAllocation no_gc;
// During bootstrapping, callback functions are not enabled yet.
if (isolate->bootstrapper()->IsActive()) return YES;
if (receiver->IsJSGlobalProxy()) {
- Object* receiver_context = JSGlobalProxy::cast(receiver)->native_context();
+ Object* receiver_context = JSGlobalProxy::cast(*receiver)->native_context();
if (!receiver_context->IsContext()) return NO;
// Get the native context of current top context.
@@ -772,16 +708,14 @@ static MayAccessDecision MayAccessPreCheck(Isolate* isolate,
}
-bool Isolate::MayNamedAccess(JSObject* receiver, Object* key,
+bool Isolate::MayNamedAccess(Handle<JSObject> receiver,
+ Handle<Object> key,
v8::AccessType type) {
ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded());
- // The callers of this method are not expecting a GC.
- DisallowHeapAllocation no_gc;
-
// Skip checks for hidden properties access. Note, we do not
// require existence of a context in this case.
- if (key == heap_.hidden_string()) return true;
+ if (key.is_identical_to(factory()->hidden_string())) return true;
// Check for compatibility between the security tokens in the
// current lexical context and the accessed object.
@@ -790,39 +724,30 @@ bool Isolate::MayNamedAccess(JSObject* receiver, Object* key,
MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
if (decision != UNKNOWN) return decision == YES;
- // Get named access check callback
- JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
- if (!constructor->shared()->IsApiFunction()) return false;
-
- Object* data_obj =
- constructor->shared()->get_api_func_data()->access_check_info();
- if (data_obj == heap_.undefined_value()) return false;
-
- Object* fun_obj = AccessCheckInfo::cast(data_obj)->named_callback();
- v8::NamedSecurityCallback callback =
- v8::ToCData<v8::NamedSecurityCallback>(fun_obj);
-
- if (!callback) return false;
-
HandleScope scope(this);
- Handle<JSObject> receiver_handle(receiver, this);
- Handle<Object> key_handle(key, this);
- Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
- LOG(this, ApiNamedSecurityCheck(key));
- bool result = false;
- {
- // Leaving JavaScript.
- VMState<EXTERNAL> state(this);
- result = callback(v8::Utils::ToLocal(receiver_handle),
- v8::Utils::ToLocal(key_handle),
- type,
- v8::Utils::ToLocal(data));
+ Handle<Object> data;
+ v8::NamedSecurityCallback callback;
+ { DisallowHeapAllocation no_gc;
+ AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver);
+ if (!access_check_info) return false;
+ Object* fun_obj = access_check_info->named_callback();
+ callback = v8::ToCData<v8::NamedSecurityCallback>(fun_obj);
+ if (!callback) return false;
+ data = handle(access_check_info->data(), this);
}
- return result;
+
+ LOG(this, ApiNamedSecurityCheck(*key));
+
+ // Leaving JavaScript.
+ VMState<EXTERNAL> state(this);
+ return callback(v8::Utils::ToLocal(receiver),
+ v8::Utils::ToLocal(key),
+ type,
+ v8::Utils::ToLocal(data));
}
-bool Isolate::MayIndexedAccess(JSObject* receiver,
+bool Isolate::MayIndexedAccess(Handle<JSObject> receiver,
uint32_t index,
v8::AccessType type) {
ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded());
@@ -833,34 +758,25 @@ bool Isolate::MayIndexedAccess(JSObject* receiver,
MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
if (decision != UNKNOWN) return decision == YES;
- // Get indexed access check callback
- JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
- if (!constructor->shared()->IsApiFunction()) return false;
-
- Object* data_obj =
- constructor->shared()->get_api_func_data()->access_check_info();
- if (data_obj == heap_.undefined_value()) return false;
-
- Object* fun_obj = AccessCheckInfo::cast(data_obj)->indexed_callback();
- v8::IndexedSecurityCallback callback =
- v8::ToCData<v8::IndexedSecurityCallback>(fun_obj);
-
- if (!callback) return false;
-
HandleScope scope(this);
- Handle<JSObject> receiver_handle(receiver, this);
- Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this);
- LOG(this, ApiIndexedSecurityCheck(index));
- bool result = false;
- {
- // Leaving JavaScript.
- VMState<EXTERNAL> state(this);
- result = callback(v8::Utils::ToLocal(receiver_handle),
- index,
- type,
- v8::Utils::ToLocal(data));
+ Handle<Object> data;
+ v8::IndexedSecurityCallback callback;
+ { DisallowHeapAllocation no_gc;
+ // Get named access check callback
+ AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver);
+ if (!access_check_info) return false;
+ Object* fun_obj = access_check_info->indexed_callback();
+ callback = v8::ToCData<v8::IndexedSecurityCallback>(fun_obj);
+ if (!callback) return false;
+ data = handle(access_check_info->data(), this);
}
- return result;
+
+ LOG(this, ApiIndexedSecurityCheck(index));
+
+ // Leaving JavaScript.
+ VMState<EXTERNAL> state(this);
+ return callback(
+ v8::Utils::ToLocal(receiver), index, type, v8::Utils::ToLocal(data));
}
@@ -868,23 +784,29 @@ const char* const Isolate::kStackOverflowMessage =
"Uncaught RangeError: Maximum call stack size exceeded";
-Failure* Isolate::StackOverflow() {
+Object* Isolate::StackOverflow() {
HandleScope scope(this);
// At this point we cannot create an Error object using its javascript
// constructor. Instead, we copy the pre-constructed boilerplate and
// attach the stack trace as a hidden property.
Handle<String> key = factory()->stack_overflow_string();
- Handle<JSObject> boilerplate =
- Handle<JSObject>::cast(GetProperty(this, js_builtins_object(), key));
- Handle<JSObject> exception = JSObject::Copy(boilerplate);
+ Handle<JSObject> boilerplate = Handle<JSObject>::cast(
+ Object::GetProperty(js_builtins_object(), key).ToHandleChecked());
+ Handle<JSObject> exception = factory()->CopyJSObject(boilerplate);
DoThrow(*exception, NULL);
// Get stack trace limit.
- Handle<Object> error = GetProperty(js_builtins_object(), "$Error");
- if (!error->IsJSObject()) return Failure::Exception();
+ Handle<Object> error = Object::GetProperty(
+ this, js_builtins_object(), "$Error").ToHandleChecked();
+ if (!error->IsJSObject()) return heap()->exception();
+
+ Handle<String> stackTraceLimit =
+ factory()->InternalizeUtf8String("stackTraceLimit");
+ ASSERT(!stackTraceLimit.is_null());
Handle<Object> stack_trace_limit =
- GetProperty(Handle<JSObject>::cast(error), "stackTraceLimit");
- if (!stack_trace_limit->IsNumber()) return Failure::Exception();
+ JSObject::GetDataProperty(Handle<JSObject>::cast(error),
+ stackTraceLimit);
+ if (!stack_trace_limit->IsNumber()) return heap()->exception();
double dlimit = stack_trace_limit->Number();
int limit = std::isnan(dlimit) ? 0 : static_cast<int>(dlimit);
@@ -893,13 +815,13 @@ Failure* Isolate::StackOverflow() {
JSObject::SetHiddenProperty(exception,
factory()->hidden_stack_trace_string(),
stack_trace);
- return Failure::Exception();
+ return heap()->exception();
}
-Failure* Isolate::TerminateExecution() {
+Object* Isolate::TerminateExecution() {
DoThrow(heap_.termination_exception(), NULL);
- return Failure::Exception();
+ return heap()->exception();
}
@@ -920,13 +842,13 @@ void Isolate::CancelTerminateExecution() {
}
-Failure* Isolate::Throw(Object* exception, MessageLocation* location) {
+Object* Isolate::Throw(Object* exception, MessageLocation* location) {
DoThrow(exception, location);
- return Failure::Exception();
+ return heap()->exception();
}
-Failure* Isolate::ReThrow(MaybeObject* exception) {
+Object* Isolate::ReThrow(Object* exception) {
bool can_be_caught_externally = false;
bool catchable_by_javascript = is_catchable_by_javascript(exception);
ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
@@ -936,18 +858,17 @@ Failure* Isolate::ReThrow(MaybeObject* exception) {
// Set the exception being re-thrown.
set_pending_exception(exception);
- if (exception->IsFailure()) return exception->ToFailureUnchecked();
- return Failure::Exception();
+ return heap()->exception();
}
-Failure* Isolate::ThrowIllegalOperation() {
+Object* Isolate::ThrowIllegalOperation() {
if (FLAG_stack_trace_on_illegal) PrintStack(stdout);
return Throw(heap_.illegal_access_string());
}
-Failure* Isolate::ThrowInvalidStringLength() {
+Object* Isolate::ThrowInvalidStringLength() {
return Throw(*factory()->NewRangeError(
"invalid_string_length", HandleVector<Object>(NULL, 0)));
}
@@ -982,8 +903,8 @@ void Isolate::RestorePendingMessageFromTryCatch(v8::TryCatch* handler) {
}
-Failure* Isolate::PromoteScheduledException() {
- MaybeObject* thrown = scheduled_exception();
+Object* Isolate::PromoteScheduledException() {
+ Object* thrown = scheduled_exception();
clear_scheduled_exception();
// Re-throw the exception to avoid getting repeated error reporting.
return ReThrow(thrown);
@@ -1070,15 +991,17 @@ bool Isolate::ShouldReportException(bool* can_be_caught_externally,
bool Isolate::IsErrorObject(Handle<Object> obj) {
if (!obj->IsJSObject()) return false;
- String* error_key =
- *(factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("$Error")));
- Object* error_constructor =
- js_builtins_object()->GetPropertyNoExceptionThrown(error_key);
+ Handle<String> error_key =
+ factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("$Error"));
+ Handle<Object> error_constructor = Object::GetProperty(
+ js_builtins_object(), error_key).ToHandleChecked();
+ DisallowHeapAllocation no_gc;
for (Object* prototype = *obj; !prototype->IsNull();
prototype = prototype->GetPrototype(this)) {
if (!prototype->IsJSObject()) return false;
- if (JSObject::cast(prototype)->map()->constructor() == error_constructor) {
+ if (JSObject::cast(prototype)->map()->constructor() ==
+ *error_constructor) {
return true;
}
}
@@ -1106,12 +1029,10 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) {
thread_local_top()->rethrowing_message_ = false;
-#ifdef ENABLE_DEBUGGER_SUPPORT
// Notify debugger of exception.
if (catchable_by_javascript) {
debugger_->OnException(exception_handle, report_exception);
}
-#endif
// Generate the message if required.
if (report_exception || try_catch_needs_message) {
@@ -1129,7 +1050,7 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) {
if (capture_stack_trace_for_uncaught_exceptions_) {
if (IsErrorObject(exception_handle)) {
// We fetch the stack trace that corresponds to this error object.
- String* key = heap()->hidden_stack_trace_string();
+ Handle<String> key = factory()->hidden_stack_trace_string();
Object* stack_property =
JSObject::cast(*exception_handle)->GetHiddenProperty(key);
// Property lookup may have failed. In this case it's probably not
@@ -1151,10 +1072,9 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) {
// before throwing as uncaught exception. Note that the pending
// exception object to be set later must not be turned into a string.
if (exception_arg->IsJSObject() && !IsErrorObject(exception_arg)) {
- bool failed = false;
- exception_arg =
- Execution::ToDetailString(this, exception_arg, &failed);
- if (failed) {
+ MaybeHandle<Object> maybe_exception =
+ Execution::ToDetailString(this, exception_arg);
+ if (!maybe_exception.ToHandle(&exception_arg)) {
exception_arg = factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("exception"));
}
@@ -1192,19 +1112,19 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) {
// In this case we could have an extension (or an internal error
// somewhere) and we print out the line number at which the error occured
// to the console for easier debugging.
- int line_number = GetScriptLineNumberSafe(location->script(),
- location->start_pos());
+ int line_number =
+ location->script()->GetLineNumber(location->start_pos()) + 1;
if (exception->IsString() && location->script()->name()->IsString()) {
OS::PrintError(
"Extension or internal compilation error: %s in %s at line %d.\n",
String::cast(exception)->ToCString().get(),
String::cast(location->script()->name())->ToCString().get(),
- line_number + 1);
+ line_number);
} else if (location->script()->name()->IsString()) {
OS::PrintError(
"Extension or internal compilation error in %s at line %d.\n",
String::cast(location->script()->name())->ToCString().get(),
- line_number + 1);
+ line_number);
} else {
OS::PrintError("Extension or internal compilation error.\n");
}
@@ -1271,7 +1191,7 @@ void Isolate::ReportPendingMessages() {
HandleScope scope(this);
if (thread_local_top_.pending_exception_ ==
- heap()->termination_exception()) {
+ heap()->termination_exception()) {
// Do nothing: if needed, the exception has been already propagated to
// v8::TryCatch.
} else {
@@ -1381,7 +1301,6 @@ Handle<Context> Isolate::global_context() {
Handle<Context> Isolate::GetCallingNativeContext() {
JavaScriptFrameIterator it(this);
-#ifdef ENABLE_DEBUGGER_SUPPORT
if (debug_->InDebugger()) {
while (!it.done()) {
JavaScriptFrame* frame = it.frame();
@@ -1393,7 +1312,6 @@ Handle<Context> Isolate::GetCallingNativeContext() {
}
}
}
-#endif // ENABLE_DEBUGGER_SUPPORT
if (it.done()) return Handle<Context>::null();
JavaScriptFrame* frame = it.frame();
Context* context = Context::cast(frame->context());
@@ -1504,10 +1422,10 @@ Isolate::Isolate()
compilation_cache_(NULL),
counters_(NULL),
code_range_(NULL),
- debugger_initialized_(false),
logger_(NULL),
stats_table_(NULL),
stub_cache_(NULL),
+ code_aging_helper_(NULL),
deoptimizer_data_(NULL),
materialized_object_store_(NULL),
capture_stack_trace_for_uncaught_exceptions_(false),
@@ -1565,11 +1483,6 @@ Isolate::Isolate()
memset(&js_spill_information_, 0, sizeof(js_spill_information_));
#endif
-#ifdef ENABLE_DEBUGGER_SUPPORT
- debug_ = NULL;
- debugger_ = NULL;
-#endif
-
handle_scope_data_.Initialize();
#define ISOLATE_INIT_EXECUTE(type, name, initial_value) \
@@ -1581,6 +1494,10 @@ Isolate::Isolate()
memset(name##_, 0, sizeof(type) * length);
ISOLATE_INIT_ARRAY_LIST(ISOLATE_INIT_ARRAY_EXECUTE)
#undef ISOLATE_INIT_ARRAY_EXECUTE
+
+ InitializeLoggingAndCounters();
+ debug_ = new Debug(this);
+ debugger_ = new Debugger(this);
}
@@ -1624,9 +1541,7 @@ void Isolate::Deinit() {
if (state_ == INITIALIZED) {
TRACE_ISOLATE(deinit);
-#ifdef ENABLE_DEBUGGER_SUPPORT
debugger()->UnloadDebugger();
-#endif
if (concurrent_recompilation_enabled()) {
optimizing_compiler_thread_->Stop();
@@ -1713,10 +1628,7 @@ Isolate::~Isolate() {
// Has to be called while counters_ are still alive
runtime_zone_.DeleteKeptSegment();
- // The entry stack must be empty when we get here,
- // except for the default isolate, where it can
- // still contain up to one entry stack item
- ASSERT(entry_stack_ == NULL || this == default_isolate_);
+ // The entry stack must be empty when we get here.
ASSERT(entry_stack_ == NULL || entry_stack_->previous_item == NULL);
delete entry_stack_;
@@ -1749,6 +1661,8 @@ Isolate::~Isolate() {
delete stub_cache_;
stub_cache_ = NULL;
+ delete code_aging_helper_;
+ code_aging_helper_ = NULL;
delete stats_table_;
stats_table_ = NULL;
@@ -1797,12 +1711,10 @@ Isolate::~Isolate() {
delete random_number_generator_;
random_number_generator_ = NULL;
-#ifdef ENABLE_DEBUGGER_SUPPORT
delete debugger_;
debugger_ = NULL;
delete debug_;
debug_ = NULL;
-#endif
}
@@ -1827,9 +1739,6 @@ void Isolate::PropagatePendingExceptionToExternalTryCatch() {
try_catch_handler()->exception_ = heap()->null_value();
} else {
v8::TryCatch* handler = try_catch_handler();
- // At this point all non-object (failure) exceptions have
- // been dealt with so this shouldn't fail.
- ASSERT(!pending_exception()->IsFailure());
ASSERT(thread_local_top_.pending_message_obj_->IsJSMessageObject() ||
thread_local_top_.pending_message_obj_->IsTheHole());
ASSERT(thread_local_top_.pending_message_script_->IsScript() ||
@@ -1858,18 +1767,6 @@ void Isolate::InitializeLoggingAndCounters() {
}
-void Isolate::InitializeDebugger() {
-#ifdef ENABLE_DEBUGGER_SUPPORT
- LockGuard<RecursiveMutex> lock_guard(debugger_access());
- if (NoBarrier_Load(&debugger_initialized_)) return;
- InitializeLoggingAndCounters();
- debug_ = new Debug(this);
- debugger_ = new Debugger(this);
- Release_Store(&debugger_initialized_, true);
-#endif
-}
-
-
bool Isolate::Init(Deserializer* des) {
ASSERT(state_ != INITIALIZED);
TRACE_ISOLATE(init);
@@ -1879,8 +1776,8 @@ bool Isolate::Init(Deserializer* des) {
has_fatal_error_ = false;
use_crankshaft_ = FLAG_crankshaft
- && !Serializer::enabled()
- && CPU::SupportsCrankshaft();
+ && !Serializer::enabled(this)
+ && CpuFeatures::SupportsCrankshaft();
if (function_entry_hook() != NULL) {
// When function entry hooking is in effect, we have to create the code
@@ -1893,10 +1790,6 @@ bool Isolate::Init(Deserializer* des) {
// The initialization process does not handle memory exhaustion.
DisallowAllocationFailure disallow_allocation_failure(this);
- InitializeLoggingAndCounters();
-
- InitializeDebugger();
-
memory_allocator_ = new MemoryAllocator(this);
code_range_ = new CodeRange(this);
@@ -1944,6 +1837,8 @@ bool Isolate::Init(Deserializer* des) {
#endif
#endif
+ code_aging_helper_ = new CodeAgingHelper();
+
{ // NOLINT
// Ensure that the thread has a valid stack guard. The v8::Locker object
// will ensure this too, but we don't have to use lockers if we are only
@@ -2011,10 +1906,6 @@ bool Isolate::Init(Deserializer* des) {
}
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
- debug_->SetUp(create_heap_objects);
-#endif
-
// If we are deserializing, read the state into the now-empty heap.
if (!create_heap_objects) {
des->Deserialize(this);
@@ -2073,7 +1964,7 @@ bool Isolate::Init(Deserializer* des) {
kDeoptTableSerializeEntryCount - 1);
}
- if (!Serializer::enabled()) {
+ if (!Serializer::enabled(this)) {
// Ensure that all stubs which need to be generated ahead of time, but
// cannot be serialized into the snapshot have been generated.
HandleScope scope(this);
@@ -2310,11 +2201,57 @@ Handle<JSObject> Isolate::GetSymbolRegistry() {
Handle<String> name = factory()->InternalizeUtf8String(nested[i]);
Handle<JSObject> obj = factory()->NewJSObjectFromMap(map);
JSObject::NormalizeProperties(obj, KEEP_INOBJECT_PROPERTIES, 8);
- JSObject::SetProperty(registry, name, obj, NONE, STRICT);
+ JSObject::SetProperty(registry, name, obj, NONE, STRICT).Assert();
}
}
return Handle<JSObject>::cast(factory()->symbol_registry());
}
+void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
+ for (int i = 0; i < call_completed_callbacks_.length(); i++) {
+ if (callback == call_completed_callbacks_.at(i)) return;
+ }
+ call_completed_callbacks_.Add(callback);
+}
+
+
+void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
+ for (int i = 0; i < call_completed_callbacks_.length(); i++) {
+ if (callback == call_completed_callbacks_.at(i)) {
+ call_completed_callbacks_.Remove(i);
+ }
+ }
+}
+
+
+void Isolate::FireCallCompletedCallback() {
+ bool has_call_completed_callbacks = !call_completed_callbacks_.is_empty();
+ bool run_microtasks = autorun_microtasks() && microtask_pending();
+ if (!has_call_completed_callbacks && !run_microtasks) return;
+
+ if (!handle_scope_implementer()->CallDepthIsZero()) return;
+ // Fire callbacks. Increase call depth to prevent recursive callbacks.
+ handle_scope_implementer()->IncrementCallDepth();
+ if (run_microtasks) Execution::RunMicrotasks(this);
+ for (int i = 0; i < call_completed_callbacks_.length(); i++) {
+ call_completed_callbacks_.at(i)();
+ }
+ handle_scope_implementer()->DecrementCallDepth();
+}
+
+
+void Isolate::RunMicrotasks() {
+ if (!microtask_pending())
+ return;
+
+ ASSERT(handle_scope_implementer()->CallDepthIsZero());
+
+ // Increase call depth to prevent recursive callbacks.
+ handle_scope_implementer()->IncrementCallDepth();
+ Execution::RunMicrotasks(this);
+ handle_scope_implementer()->DecrementCallDepth();
+}
+
+
} } // namespace v8::internal
diff --git a/deps/v8/src/isolate.h b/deps/v8/src/isolate.h
index b4713786ab..5b1e77f20e 100644
--- a/deps/v8/src/isolate.h
+++ b/deps/v8/src/isolate.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ISOLATE_H_
#define V8_ISOLATE_H_
@@ -77,6 +54,7 @@ class InlineRuntimeFunctionsTable;
class InnerPointerToCodeCache;
class MaterializedObjectStore;
class NoAllocationStringAllocator;
+class CodeAgingHelper;
class RandomNumberGenerator;
class RegExpStack;
class SaveContext;
@@ -95,11 +73,9 @@ template <StateTag Tag> class VMState;
typedef void* ExternalReferenceRedirectorPointer();
-#ifdef ENABLE_DEBUGGER_SUPPORT
class Debug;
class Debugger;
class DebuggerAgent;
-#endif
#if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
!defined(__aarch64__) && V8_TARGET_ARCH_ARM64 || \
@@ -117,7 +93,7 @@ class Simulator;
// of handles to the actual constants.
typedef ZoneList<Handle<Object> > ZoneObjectList;
-#define RETURN_IF_SCHEDULED_EXCEPTION(isolate) \
+#define RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate) \
do { \
Isolate* __isolate__ = (isolate); \
if (__isolate__->has_scheduled_exception()) { \
@@ -125,31 +101,46 @@ typedef ZoneList<Handle<Object> > ZoneObjectList;
} \
} while (false)
-#define RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, T) \
- do { \
- Isolate* __isolate__ = (isolate); \
- if (__isolate__->has_scheduled_exception()) { \
- __isolate__->PromoteScheduledException(); \
- return Handle<T>::null(); \
- } \
+// Macros for MaybeHandle.
+
+#define RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, T) \
+ do { \
+ Isolate* __isolate__ = (isolate); \
+ if (__isolate__->has_scheduled_exception()) { \
+ __isolate__->PromoteScheduledException(); \
+ return MaybeHandle<T>(); \
+ } \
} while (false)
-#define RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, value) \
- do { \
- if ((call).is_null()) { \
- ASSERT((isolate)->has_pending_exception()); \
- return (value); \
- } \
+#define ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value) \
+ do { \
+ if (!(call).ToHandle(&dst)) { \
+ ASSERT((isolate)->has_pending_exception()); \
+ return value; \
+ } \
} while (false)
-#define CHECK_NOT_EMPTY_HANDLE(isolate, call) \
- do { \
- ASSERT(!(isolate)->has_pending_exception()); \
- CHECK(!(call).is_null()); \
+#define ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call) \
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE( \
+ isolate, dst, call, isolate->heap()->exception())
+
+#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call, T) \
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, MaybeHandle<T>())
+
+#define RETURN_ON_EXCEPTION_VALUE(isolate, call, value) \
+ do { \
+ if ((call).is_null()) { \
+ ASSERT((isolate)->has_pending_exception()); \
+ return value; \
+ } \
} while (false)
-#define RETURN_IF_EMPTY_HANDLE(isolate, call) \
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, Failure::Exception())
+#define RETURN_FAILURE_ON_EXCEPTION(isolate, call) \
+ RETURN_ON_EXCEPTION_VALUE(isolate, call, isolate->heap()->exception())
+
+#define RETURN_ON_EXCEPTION(isolate, call, T) \
+ RETURN_ON_EXCEPTION_VALUE(isolate, call, MaybeHandle<T>())
+
#define FOR_EACH_ISOLATE_ADDRESS_NAME(C) \
C(Handler, handler) \
@@ -251,7 +242,7 @@ class ThreadLocalTop BASE_EMBEDDED {
// lookups.
Context* context_;
ThreadId thread_id_;
- MaybeObject* pending_exception_;
+ Object* pending_exception_;
bool has_pending_message_;
bool rethrowing_message_;
Object* pending_message_obj_;
@@ -261,7 +252,7 @@ class ThreadLocalTop BASE_EMBEDDED {
// Use a separate value for scheduled exceptions to preserve the
// invariants that hold about pending_exception. We may want to
// unify them later.
- MaybeObject* scheduled_exception_;
+ Object* scheduled_exception_;
bool external_caught_exception_;
SaveContext* save_context_;
v8::TryCatch* catcher_;
@@ -295,17 +286,6 @@ class ThreadLocalTop BASE_EMBEDDED {
};
-#ifdef ENABLE_DEBUGGER_SUPPORT
-
-#define ISOLATE_DEBUGGER_INIT_LIST(V) \
- V(DebuggerAgent*, debugger_agent_instance, NULL)
-#else
-
-#define ISOLATE_DEBUGGER_INIT_LIST(V)
-
-#endif
-
-
#if V8_TARGET_ARCH_ARM && !defined(__arm__) || \
V8_TARGET_ARCH_ARM64 && !defined(__aarch64__) || \
V8_TARGET_ARCH_MIPS && !defined(__mips__)
@@ -378,8 +358,8 @@ typedef List<HeapObject*> DebugObjectCache;
V(bool, fp_stubs_generated, false) \
V(int, max_available_threads, 0) \
V(uint32_t, per_isolate_assert_data, 0xFFFFFFFFu) \
- ISOLATE_INIT_SIMULATOR_LIST(V) \
- ISOLATE_DEBUGGER_INIT_LIST(V)
+ V(DebuggerAgent*, debugger_agent_instance, NULL) \
+ ISOLATE_INIT_SIMULATOR_LIST(V)
#define THREAD_LOCAL_TOP_ACCESSOR(type, name) \
inline void set_##name(type v) { thread_local_top_.name##_ = v; } \
@@ -515,16 +495,6 @@ class Isolate {
// If one does not yet exist, return null.
PerIsolateThreadData* FindPerThreadDataForThread(ThreadId thread_id);
-#ifdef ENABLE_DEBUGGER_SUPPORT
- // Get the debugger from the default isolate. Preinitializes the
- // default isolate if needed.
- static Debugger* GetDefaultIsolateDebugger();
-#endif
-
- // Get the stack guard from the default isolate. Preinitializes the
- // default isolate if needed.
- static StackGuard* GetDefaultIsolateStackGuard();
-
// Returns the key used to store the pointer to the current isolate.
// Used internally for V8 threads that do not execute JavaScript but still
// are part of the domain of an isolate (like the context switcher).
@@ -539,12 +509,6 @@ class Isolate {
static Thread::LocalStorageKey per_isolate_thread_data_key();
- // If a client attempts to create a Locker without specifying an isolate,
- // we assume that the client is using legacy behavior. Set up the current
- // thread to be inside the implicit isolate (or fail a check if we have
- // switched to non-legacy behavior).
- static void EnterDefaultIsolate();
-
// Mutex for serializing access to break control structures.
RecursiveMutex* break_access() { return &break_access_; }
@@ -567,24 +531,28 @@ class Isolate {
THREAD_LOCAL_TOP_ACCESSOR(ThreadId, thread_id)
// Interface to pending exception.
- MaybeObject* pending_exception() {
+ Object* pending_exception() {
ASSERT(has_pending_exception());
+ ASSERT(!thread_local_top_.pending_exception_->IsException());
return thread_local_top_.pending_exception_;
}
- void set_pending_exception(MaybeObject* exception) {
- thread_local_top_.pending_exception_ = exception;
+ void set_pending_exception(Object* exception_obj) {
+ ASSERT(!exception_obj->IsException());
+ thread_local_top_.pending_exception_ = exception_obj;
}
void clear_pending_exception() {
+ ASSERT(!thread_local_top_.pending_exception_->IsException());
thread_local_top_.pending_exception_ = heap_.the_hole_value();
}
- MaybeObject** pending_exception_address() {
+ Object** pending_exception_address() {
return &thread_local_top_.pending_exception_;
}
bool has_pending_exception() {
+ ASSERT(!thread_local_top_.pending_exception_->IsException());
return !thread_local_top_.pending_exception_->IsTheHole();
}
@@ -607,7 +575,7 @@ class Isolate {
THREAD_LOCAL_TOP_ACCESSOR(v8::TryCatch*, catcher)
- MaybeObject** scheduled_exception_address() {
+ Object** scheduled_exception_address() {
return &thread_local_top_.scheduled_exception_;
}
@@ -624,20 +592,23 @@ class Isolate {
&thread_local_top_.pending_message_script_);
}
- MaybeObject* scheduled_exception() {
+ Object* scheduled_exception() {
ASSERT(has_scheduled_exception());
+ ASSERT(!thread_local_top_.scheduled_exception_->IsException());
return thread_local_top_.scheduled_exception_;
}
bool has_scheduled_exception() {
+ ASSERT(!thread_local_top_.scheduled_exception_->IsException());
return thread_local_top_.scheduled_exception_ != heap_.the_hole_value();
}
void clear_scheduled_exception() {
+ ASSERT(!thread_local_top_.scheduled_exception_->IsException());
thread_local_top_.scheduled_exception_ = heap_.the_hole_value();
}
bool IsExternallyCaught();
- bool is_catchable_by_javascript(MaybeObject* exception) {
+ bool is_catchable_by_javascript(Object* exception) {
return exception != heap()->termination_exception();
}
@@ -693,11 +664,10 @@ class Isolate {
class ExceptionScope {
public:
explicit ExceptionScope(Isolate* isolate) :
- // Scope currently can only be used for regular exceptions, not
- // failures like OOM or termination exception.
+ // Scope currently can only be used for regular exceptions,
+ // not termination exception.
isolate_(isolate),
- pending_exception_(isolate_->pending_exception()->ToObjectUnchecked(),
- isolate_),
+ pending_exception_(isolate_->pending_exception(), isolate_),
catcher_(isolate_->catcher())
{ }
@@ -738,39 +708,31 @@ class Isolate {
// the result is false, the pending exception is guaranteed to be
// set.
- // TODO(yangguo): temporary wrappers
- bool MayNamedAccessWrapper(Handle<JSObject> receiver,
- Handle<Object> key,
- v8::AccessType type) {
- return MayNamedAccess(*receiver, *key, type);
- }
- bool MayIndexedAccessWrapper(Handle<JSObject> receiver,
- uint32_t index,
- v8::AccessType type) {
- return MayIndexedAccess(*receiver, index, type);
- }
- void ReportFailedAccessCheckWrapper(Handle<JSObject> receiver,
- v8::AccessType type) {
- ReportFailedAccessCheck(*receiver, type);
- }
-
- bool MayNamedAccess(JSObject* receiver,
- Object* key,
+ bool MayNamedAccess(Handle<JSObject> receiver,
+ Handle<Object> key,
v8::AccessType type);
- bool MayIndexedAccess(JSObject* receiver,
+ bool MayIndexedAccess(Handle<JSObject> receiver,
uint32_t index,
v8::AccessType type);
void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback);
- void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type);
+ void ReportFailedAccessCheck(Handle<JSObject> receiver, v8::AccessType type);
// Exception throwing support. The caller should use the result
// of Throw() as its return value.
- Failure* Throw(Object* exception, MessageLocation* location = NULL);
+ Object* Throw(Object* exception, MessageLocation* location = NULL);
+
+ template <typename T>
+ MUST_USE_RESULT MaybeHandle<T> Throw(Handle<Object> exception,
+ MessageLocation* location = NULL) {
+ Throw(*exception, location);
+ return MaybeHandle<T>();
+ }
+
// Re-throw an exception. This involves no error reporting since
// error reporting was handled when the exception was thrown
// originally.
- Failure* ReThrow(MaybeObject* exception);
+ Object* ReThrow(Object* exception);
void ScheduleThrow(Object* exception);
// Re-set pending message, script and positions reported to the TryCatch
// back to the TLS for re-use when rethrowing.
@@ -778,11 +740,11 @@ class Isolate {
void ReportPendingMessages();
// Return pending location if any or unfilled structure.
MessageLocation GetMessageLocation();
- Failure* ThrowIllegalOperation();
- Failure* ThrowInvalidStringLength();
+ Object* ThrowIllegalOperation();
+ Object* ThrowInvalidStringLength();
// Promote a scheduled exception to pending. Asserts has_scheduled_exception.
- Failure* PromoteScheduledException();
+ Object* PromoteScheduledException();
void DoThrow(Object* exception, MessageLocation* location);
// Checks if exception should be reported and finds out if it's
// caught externally.
@@ -794,8 +756,8 @@ class Isolate {
void ComputeLocation(MessageLocation* target);
// Out of resource exception helpers.
- Failure* StackOverflow();
- Failure* TerminateExecution();
+ Object* StackOverflow();
+ Object* TerminateExecution();
void CancelTerminateExecution();
// Administration
@@ -875,6 +837,7 @@ class Isolate {
Heap* heap() { return &heap_; }
StatsTable* stats_table();
StubCache* stub_cache() { return stub_cache_; }
+ CodeAgingHelper* code_aging_helper() { return code_aging_helper_; }
DeoptimizerData* deoptimizer_data() { return deoptimizer_data_; }
ThreadLocalTop* thread_local_top() { return &thread_local_top_; }
MaterializedObjectStore* materialized_object_store() {
@@ -967,16 +930,8 @@ class Isolate {
inline bool IsCodePreAgingActive();
-#ifdef ENABLE_DEBUGGER_SUPPORT
- Debugger* debugger() {
- if (!NoBarrier_Load(&debugger_initialized_)) InitializeDebugger();
- return debugger_;
- }
- Debug* debug() {
- if (!NoBarrier_Load(&debugger_initialized_)) InitializeDebugger();
- return debug_;
- }
-#endif
+ Debugger* debugger() { return debugger_; }
+ Debug* debug() { return debug_; }
inline bool IsDebuggerActive();
inline bool DebuggerHasBreakPoints();
@@ -1085,11 +1040,6 @@ class Isolate {
return sweeper_thread_;
}
- // PreInits and returns a default isolate. Needed when a new thread tries
- // to create a Locker for the first time (the lock itself is in the isolate).
- // TODO(svenpanne) This method is on death row...
- static v8::Isolate* GetDefaultIsolateForLocking();
-
int id() const { return static_cast<int>(id_); }
HStatistics* GetHStatistics();
@@ -1119,6 +1069,12 @@ class Isolate {
// Get (and lazily initialize) the registry for per-isolate symbols.
Handle<JSObject> GetSymbolRegistry();
+ void AddCallCompletedCallback(CallCompletedCallback callback);
+ void RemoveCallCompletedCallback(CallCompletedCallback callback);
+ void FireCallCompletedCallback();
+
+ void RunMicrotasks();
+
private:
Isolate();
@@ -1222,8 +1178,6 @@ class Isolate {
void PropagatePendingExceptionToExternalTryCatch();
- void InitializeDebugger();
-
// Traverse prototype chain to find out whether the object is derived from
// the Error object.
bool IsErrorObject(Handle<Object> obj);
@@ -1245,6 +1199,7 @@ class Isolate {
StackGuard stack_guard_;
StatsTable* stats_table_;
StubCache* stub_cache_;
+ CodeAgingHelper* code_aging_helper_;
DeoptimizerData* deoptimizer_data_;
MaterializedObjectStore* materialized_object_store_;
ThreadLocalTop thread_local_top_;
@@ -1300,10 +1255,8 @@ class Isolate {
JSObject::SpillInformation js_spill_information_;
#endif
-#ifdef ENABLE_DEBUGGER_SUPPORT
Debugger* debugger_;
Debug* debug_;
-#endif
CpuProfiler* cpu_profiler_;
HeapProfiler* heap_profiler_;
FunctionEntryHook function_entry_hook_;
@@ -1339,6 +1292,9 @@ class Isolate {
int next_optimization_id_;
+ // List of callbacks when a Call completes.
+ List<CallCompletedCallback> call_completed_callbacks_;
+
friend class ExecutionAccess;
friend class HandleScopeImplementer;
friend class IsolateInitializer;
diff --git a/deps/v8/src/json-parser.h b/deps/v8/src/json-parser.h
index 4c2b479182..f3017784bc 100644
--- a/deps/v8/src/json-parser.h
+++ b/deps/v8/src/json-parser.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_JSON_PARSER_H_
#define V8_JSON_PARSER_H_
@@ -31,7 +8,7 @@
#include "v8.h"
#include "char-predicates-inl.h"
-#include "v8conversions.h"
+#include "conversions.h"
#include "messages.h"
#include "spaces-inl.h"
#include "token.h"
@@ -43,7 +20,7 @@ namespace internal {
template <bool seq_ascii>
class JsonParser BASE_EMBEDDED {
public:
- static Handle<Object> Parse(Handle<String> source) {
+ MUST_USE_RESULT static MaybeHandle<Object> Parse(Handle<String> source) {
return JsonParser(source).ParseJson();
}
@@ -59,7 +36,7 @@ class JsonParser BASE_EMBEDDED {
object_constructor_(isolate_->native_context()->object_function(),
isolate_),
position_(-1) {
- FlattenString(source_);
+ source_ = String::Flatten(source_);
pretenure_ = (source_length_ >= kPretenureTreshold) ? TENURED : NOT_TENURED;
// Optimized fast case where we only have ASCII characters.
@@ -69,7 +46,7 @@ class JsonParser BASE_EMBEDDED {
}
// Parse a string containing a single JSON value.
- Handle<Object> ParseJson();
+ MaybeHandle<Object> ParseJson();
inline void Advance() {
position_++;
@@ -219,7 +196,7 @@ class JsonParser BASE_EMBEDDED {
};
template <bool seq_ascii>
-Handle<Object> JsonParser<seq_ascii>::ParseJson() {
+MaybeHandle<Object> JsonParser<seq_ascii>::ParseJson() {
// Advance to the first character (possibly EOS)
AdvanceSkipWhitespace();
Handle<Object> result = ParseJsonValue();
@@ -257,8 +234,7 @@ Handle<Object> JsonParser<seq_ascii>::ParseJson() {
break;
default:
message = "unexpected_token";
- Handle<Object> name =
- LookupSingleCharacterStringFromCode(isolate_, c0_);
+ Handle<Object> name = factory->LookupSingleCharacterStringFromCode(c0_);
Handle<FixedArray> element = factory->NewFixedArray(1);
element->set(0, *name);
array = factory->NewJSArrayWithElements(element);
@@ -268,9 +244,8 @@ Handle<Object> JsonParser<seq_ascii>::ParseJson() {
MessageLocation location(factory->NewScript(source_),
position_,
position_ + 1);
- Handle<Object> result = factory->NewSyntaxError(message, array);
- isolate()->Throw(*result, &location);
- return Handle<Object>::null();
+ Handle<Object> error = factory->NewSyntaxError(message, array);
+ return isolate()->template Throw<Object>(error, &location);
}
return result;
}
@@ -361,7 +336,7 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
Handle<Object> value = ParseJsonValue();
if (value.is_null()) return ReportUnexpectedCharacter();
- JSObject::SetOwnElement(json_object, index, value, SLOPPY);
+ JSObject::SetOwnElement(json_object, index, value, SLOPPY).Assert();
continue;
}
// Not an index, fallback to the slow path.
@@ -417,7 +392,15 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
if (value->IsSmi() && expected_representation.IsDouble()) {
value = factory()->NewHeapNumber(
Handle<Smi>::cast(value)->value());
+ } else if (expected_representation.IsHeapObject() &&
+ !target->instance_descriptors()->GetFieldType(
+ descriptor)->NowContains(value)) {
+ Handle<HeapType> value_type(value->OptimalType(
+ isolate(), expected_representation));
+ Map::GeneralizeFieldType(target, descriptor, value_type);
}
+ ASSERT(target->instance_descriptors()->GetFieldType(
+ descriptor)->NowContains(value));
properties.Add(value, zone());
map = target;
continue;
@@ -443,7 +426,7 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
}
JSObject::SetLocalPropertyIgnoreAttributes(
- json_object, key, value, NONE);
+ json_object, key, value, NONE).Assert();
} while (MatchSkipWhiteSpace(','));
if (c0_ != '}') {
return ReportUnexpectedCharacter();
@@ -541,17 +524,16 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonNumber() {
if (seq_ascii) {
Vector<const uint8_t> chars(seq_source_->GetChars() + beg_pos, length);
number = StringToDouble(isolate()->unicode_cache(),
- Vector<const char>::cast(chars),
- NO_FLAGS, // Hex, octal or trailing junk.
- OS::nan_value());
+ chars,
+ NO_FLAGS, // Hex, octal or trailing junk.
+ OS::nan_value());
} else {
Vector<uint8_t> buffer = Vector<uint8_t>::New(length);
String::WriteToFlat(*source_, buffer.start(), beg_pos, position_);
Vector<const uint8_t> result =
Vector<const uint8_t>(buffer.start(), length);
number = StringToDouble(isolate()->unicode_cache(),
- // TODO(dcarney): Convert StringToDouble to uint_t.
- Vector<const char>::cast(result),
+ result,
NO_FLAGS, // Hex, octal or trailing junk.
0.0);
buffer.Dispose();
@@ -583,14 +565,14 @@ template <>
inline Handle<SeqTwoByteString> NewRawString(Factory* factory,
int length,
PretenureFlag pretenure) {
- return factory->NewRawTwoByteString(length, pretenure);
+ return factory->NewRawTwoByteString(length, pretenure).ToHandleChecked();
}
template <>
inline Handle<SeqOneByteString> NewRawString(Factory* factory,
int length,
PretenureFlag pretenure) {
- return factory->NewRawOneByteString(length, pretenure);
+ return factory->NewRawOneByteString(length, pretenure).ToHandleChecked();
}
@@ -606,7 +588,6 @@ Handle<String> JsonParser<seq_ascii>::SlowScanJsonString(
int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count));
Handle<StringType> seq_string =
NewRawString<StringType>(factory(), length, pretenure_);
- ASSERT(!seq_string.is_null());
// Copy prefix into seq_str.
SinkChar* dest = seq_string->GetChars();
String::WriteToFlat(*prefix, dest, start, end);
@@ -793,8 +774,8 @@ Handle<String> JsonParser<seq_ascii>::ScanJsonString() {
}
} while (c0_ != '"');
int length = position_ - beg_pos;
- Handle<String> result = factory()->NewRawOneByteString(length, pretenure_);
- ASSERT(!result.is_null());
+ Handle<String> result =
+ factory()->NewRawOneByteString(length, pretenure_).ToHandleChecked();
uint8_t* dest = SeqOneByteString::cast(*result)->GetChars();
String::WriteToFlat(*source_, dest, beg_pos, position_);
diff --git a/deps/v8/src/json-stringifier.h b/deps/v8/src/json-stringifier.h
index 3926969f65..7eb6746dfb 100644
--- a/deps/v8/src/json-stringifier.h
+++ b/deps/v8/src/json-stringifier.h
@@ -1,36 +1,13 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_JSON_STRINGIFIER_H_
#define V8_JSON_STRINGIFIER_H_
#include "v8.h"
-#include "v8utils.h"
-#include "v8conversions.h"
+#include "conversions.h"
+#include "utils.h"
namespace v8 {
namespace internal {
@@ -39,17 +16,18 @@ class BasicJsonStringifier BASE_EMBEDDED {
public:
explicit BasicJsonStringifier(Isolate* isolate);
- MaybeObject* Stringify(Handle<Object> object);
+ MUST_USE_RESULT MaybeHandle<Object> Stringify(Handle<Object> object);
- INLINE(static MaybeObject* StringifyString(Isolate* isolate,
- Handle<String> object));
+ MUST_USE_RESULT INLINE(static MaybeHandle<Object> StringifyString(
+ Isolate* isolate,
+ Handle<String> object));
private:
static const int kInitialPartLength = 32;
static const int kMaxPartLength = 16 * 1024;
static const int kPartLengthGrowthFactor = 2;
- enum Result { UNCHANGED, SUCCESS, EXCEPTION, CIRCULAR, STACK_OVERFLOW };
+ enum Result { UNCHANGED, SUCCESS, EXCEPTION };
void Accumulate();
@@ -81,8 +59,9 @@ class BasicJsonStringifier BASE_EMBEDDED {
}
}
- Handle<Object> ApplyToJsonFunction(Handle<Object> object,
- Handle<Object> key);
+ MUST_USE_RESULT MaybeHandle<Object> ApplyToJsonFunction(
+ Handle<Object> object,
+ Handle<Object> key);
Result SerializeGeneric(Handle<Object> object,
Handle<Object> key,
@@ -90,9 +69,9 @@ class BasicJsonStringifier BASE_EMBEDDED {
bool deferred_key);
template <typename ResultType, typename Char>
- INLINE(static MaybeObject* StringifyString_(Isolate* isolate,
- Vector<Char> vector,
- Handle<String> result));
+ INLINE(static Handle<String> StringifyString_(Isolate* isolate,
+ Vector<Char> vector,
+ Handle<String> result));
// Entry point to serialize the object.
INLINE(Result SerializeObject(Handle<Object> obj)) {
@@ -140,7 +119,7 @@ class BasicJsonStringifier BASE_EMBEDDED {
INLINE(Result SerializeJSArray(Handle<JSArray> object));
INLINE(Result SerializeJSObject(Handle<JSObject> object));
- Result SerializeJSArraySlow(Handle<JSArray> object, int length);
+ Result SerializeJSArraySlow(Handle<JSArray> object, uint32_t length);
void SerializeString(Handle<String> object);
@@ -263,38 +242,33 @@ BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate)
overflowed_(false) {
factory_ = isolate_->factory();
accumulator_store_ = Handle<JSValue>::cast(
- factory_->ToObject(factory_->empty_string()));
+ Object::ToObject(isolate, factory_->empty_string()).ToHandleChecked());
part_length_ = kInitialPartLength;
- current_part_ = factory_->NewRawOneByteString(part_length_);
- ASSERT(!current_part_.is_null());
+ current_part_ = factory_->NewRawOneByteString(part_length_).ToHandleChecked();
tojson_string_ = factory_->toJSON_string();
stack_ = factory_->NewJSArray(8);
}
-MaybeObject* BasicJsonStringifier::Stringify(Handle<Object> object) {
- switch (SerializeObject(object)) {
- case UNCHANGED:
- return isolate_->heap()->undefined_value();
- case SUCCESS: {
- ShrinkCurrentPart();
- Accumulate();
- if (overflowed_) return isolate_->ThrowInvalidStringLength();
- return *accumulator();
+MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object) {
+ Result result = SerializeObject(object);
+ if (result == UNCHANGED) return isolate_->factory()->undefined_value();
+ if (result == SUCCESS) {
+ ShrinkCurrentPart();
+ Accumulate();
+ if (overflowed_) {
+ return isolate_->Throw<Object>(
+ isolate_->factory()->NewInvalidStringLengthError());
}
- case CIRCULAR:
- return isolate_->Throw(*factory_->NewTypeError(
- "circular_structure", HandleVector<Object>(NULL, 0)));
- case STACK_OVERFLOW:
- return isolate_->StackOverflow();
- default:
- return Failure::Exception();
+ return accumulator();
}
+ ASSERT(result == EXCEPTION);
+ return MaybeHandle<Object>();
}
-MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate,
- Handle<String> object) {
+MaybeHandle<Object> BasicJsonStringifier::StringifyString(
+ Isolate* isolate, Handle<String> object) {
static const int kJsonQuoteWorstCaseBlowup = 6;
static const int kSpaceForQuotes = 2;
int worst_case_length =
@@ -305,21 +279,19 @@ MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate,
return stringifier.Stringify(object);
}
- FlattenString(object);
+ object = String::Flatten(object);
ASSERT(object->IsFlat());
if (object->IsOneByteRepresentationUnderneath()) {
- Handle<String> result =
- isolate->factory()->NewRawOneByteString(worst_case_length);
- ASSERT(!result.is_null());
+ Handle<String> result = isolate->factory()->NewRawOneByteString(
+ worst_case_length).ToHandleChecked();
DisallowHeapAllocation no_gc;
return StringifyString_<SeqOneByteString>(
isolate,
object->GetFlatContent().ToOneByteVector(),
result);
} else {
- Handle<String> result =
- isolate->factory()->NewRawTwoByteString(worst_case_length);
- ASSERT(!result.is_null());
+ Handle<String> result = isolate->factory()->NewRawTwoByteString(
+ worst_case_length).ToHandleChecked();
DisallowHeapAllocation no_gc;
return StringifyString_<SeqTwoByteString>(
isolate,
@@ -330,9 +302,9 @@ MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate,
template <typename ResultType, typename Char>
-MaybeObject* BasicJsonStringifier::StringifyString_(Isolate* isolate,
- Vector<Char> vector,
- Handle<String> result) {
+Handle<String> BasicJsonStringifier::StringifyString_(Isolate* isolate,
+ Vector<Char> vector,
+ Handle<String> result) {
DisallowHeapAllocation no_gc;
int final_size = 0;
ResultType* dest = ResultType::cast(*result);
@@ -341,7 +313,7 @@ MaybeObject* BasicJsonStringifier::StringifyString_(Isolate* isolate,
dest->GetChars() + 1,
vector.length());
dest->Set(final_size++, '\"');
- return *SeqString::Truncate(Handle<SeqString>::cast(result), final_size);
+ return SeqString::Truncate(Handle<SeqString>::cast(result), final_size);
}
@@ -364,25 +336,27 @@ void BasicJsonStringifier::Append_(const Char* chars) {
}
-Handle<Object> BasicJsonStringifier::ApplyToJsonFunction(
+MaybeHandle<Object> BasicJsonStringifier::ApplyToJsonFunction(
Handle<Object> object, Handle<Object> key) {
LookupResult lookup(isolate_);
- JSObject::cast(*object)->LookupRealNamedProperty(*tojson_string_, &lookup);
+ JSObject::cast(*object)->LookupRealNamedProperty(tojson_string_, &lookup);
if (!lookup.IsProperty()) return object;
PropertyAttributes attr;
- Handle<Object> fun =
- Object::GetProperty(object, object, &lookup, tojson_string_, &attr);
- if (fun.is_null()) return Handle<Object>::null();
+ Handle<Object> fun;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate_, fun,
+ Object::GetProperty(object, object, &lookup, tojson_string_, &attr),
+ Object);
if (!fun->IsJSFunction()) return object;
// Call toJSON function.
if (key->IsSmi()) key = factory_->NumberToString(key);
Handle<Object> argv[] = { key };
- bool has_exception = false;
HandleScope scope(isolate_);
- object = Execution::Call(isolate_, fun, object, 1, argv, &has_exception);
- // Return empty handle to signal an exception.
- if (has_exception) return Handle<Object>::null();
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate_, object,
+ Execution::Call(isolate_, fun, object, 1, argv),
+ Object);
return scope.CloseAndEscape(object);
}
@@ -390,7 +364,10 @@ Handle<Object> BasicJsonStringifier::ApplyToJsonFunction(
BasicJsonStringifier::Result BasicJsonStringifier::StackPush(
Handle<Object> object) {
StackLimitCheck check(isolate_);
- if (check.HasOverflowed()) return STACK_OVERFLOW;
+ if (check.HasOverflowed()) {
+ isolate_->StackOverflow();
+ return EXCEPTION;
+ }
int length = Smi::cast(stack_->length())->value();
{
@@ -398,7 +375,10 @@ BasicJsonStringifier::Result BasicJsonStringifier::StackPush(
FixedArray* elements = FixedArray::cast(stack_->elements());
for (int i = 0; i < length; i++) {
if (elements->get(i) == *object) {
- return CIRCULAR;
+ AllowHeapAllocation allow_to_return_error;
+ isolate_->Throw(*factory_->NewTypeError(
+ "circular_structure", HandleVector<Object>(NULL, 0)));
+ return EXCEPTION;
}
}
}
@@ -419,8 +399,10 @@ template <bool deferred_string_key>
BasicJsonStringifier::Result BasicJsonStringifier::Serialize_(
Handle<Object> object, bool comma, Handle<Object> key) {
if (object->IsJSObject()) {
- object = ApplyToJsonFunction(object, key);
- if (object.is_null()) return EXCEPTION;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, object,
+ ApplyToJsonFunction(object, key),
+ EXCEPTION);
}
if (object->IsSmi()) {
@@ -479,15 +461,16 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeGeneric(
Handle<Object> key,
bool deferred_comma,
bool deferred_key) {
- Handle<JSObject> builtins(isolate_->native_context()->builtins());
- Handle<JSFunction> builtin =
- Handle<JSFunction>::cast(GetProperty(builtins, "JSONSerializeAdapter"));
+ Handle<JSObject> builtins(isolate_->native_context()->builtins(), isolate_);
+ Handle<JSFunction> builtin = Handle<JSFunction>::cast(Object::GetProperty(
+ isolate_, builtins, "JSONSerializeAdapter").ToHandleChecked());
Handle<Object> argv[] = { key, object };
- bool has_exception = false;
- Handle<Object> result =
- Execution::Call(isolate_, builtin, object, 2, argv, &has_exception);
- if (has_exception) return EXCEPTION;
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, result,
+ Execution::Call(isolate_, builtin, object, 2, argv),
+ EXCEPTION);
if (result->IsUndefined()) return UNCHANGED;
if (deferred_key) {
if (key->IsSmi()) key = factory_->NumberToString(key);
@@ -501,8 +484,11 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeGeneric(
part_length_ = kInitialPartLength; // Allocate conservatively.
Extend(); // Attach current part and allocate new part.
// Attach result string to the accumulator.
- Handle<String> cons = factory_->NewConsString(accumulator(), result_string);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate_, cons, EXCEPTION);
+ Handle<String> cons;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, cons,
+ factory_->NewConsString(accumulator(), result_string),
+ EXCEPTION);
set_accumulator(cons);
return SUCCESS;
}
@@ -510,17 +496,16 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeGeneric(
BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSValue(
Handle<JSValue> object) {
- bool has_exception = false;
String* class_name = object->class_name();
if (class_name == isolate_->heap()->String_string()) {
- Handle<Object> value =
- Execution::ToString(isolate_, object, &has_exception);
- if (has_exception) return EXCEPTION;
+ Handle<Object> value;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, value, Execution::ToString(isolate_, object), EXCEPTION);
SerializeString(Handle<String>::cast(value));
} else if (class_name == isolate_->heap()->Number_string()) {
- Handle<Object> value =
- Execution::ToNumber(isolate_, object, &has_exception);
- if (has_exception) return EXCEPTION;
+ Handle<Object> value;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, value, Execution::ToNumber(isolate_, object), EXCEPTION);
if (value->IsSmi()) return SerializeSmi(Smi::cast(*value));
SerializeHeapNumber(Handle<HeapNumber>::cast(value));
} else {
@@ -561,22 +546,25 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray(
HandleScope handle_scope(isolate_);
Result stack_push = StackPush(object);
if (stack_push != SUCCESS) return stack_push;
- int length = Smi::cast(object->length())->value();
+ uint32_t length = 0;
+ CHECK(object->length()->ToArrayIndex(&length));
Append('[');
switch (object->GetElementsKind()) {
case FAST_SMI_ELEMENTS: {
Handle<FixedArray> elements(
FixedArray::cast(object->elements()), isolate_);
- for (int i = 0; i < length; i++) {
+ for (uint32_t i = 0; i < length; i++) {
if (i > 0) Append(',');
SerializeSmi(Smi::cast(elements->get(i)));
}
break;
}
case FAST_DOUBLE_ELEMENTS: {
+ // Empty array is FixedArray but not FixedDoubleArray.
+ if (length == 0) break;
Handle<FixedDoubleArray> elements(
FixedDoubleArray::cast(object->elements()), isolate_);
- for (int i = 0; i < length; i++) {
+ for (uint32_t i = 0; i < length; i++) {
if (i > 0) Append(',');
SerializeDouble(elements->get_scalar(i));
}
@@ -585,7 +573,7 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray(
case FAST_ELEMENTS: {
Handle<FixedArray> elements(
FixedArray::cast(object->elements()), isolate_);
- for (int i = 0; i < length; i++) {
+ for (uint32_t i = 0; i < length; i++) {
if (i > 0) Append(',');
Result result =
SerializeElement(isolate_,
@@ -617,11 +605,14 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray(
BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArraySlow(
- Handle<JSArray> object, int length) {
- for (int i = 0; i < length; i++) {
+ Handle<JSArray> object, uint32_t length) {
+ for (uint32_t i = 0; i < length; i++) {
if (i > 0) Append(',');
- Handle<Object> element = Object::GetElement(isolate_, object, i);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate_, element, EXCEPTION);
+ Handle<Object> element;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, element,
+ Object::GetElement(isolate_, object, i),
+ EXCEPTION);
if (element->IsUndefined()) {
AppendAscii("null");
} else {
@@ -671,43 +662,48 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject(
map->instance_descriptors()->GetFieldIndex(i)),
isolate_);
} else {
- property = GetProperty(isolate_, object, key);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate_, property, EXCEPTION);
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, property,
+ Object::GetPropertyOrElement(object, key),
+ EXCEPTION);
}
Result result = SerializeProperty(property, comma, key);
if (!comma && result == SUCCESS) comma = true;
- if (result >= EXCEPTION) return result;
+ if (result == EXCEPTION) return result;
}
} else {
- bool has_exception = false;
- Handle<FixedArray> contents =
- GetKeysInFixedArrayFor(object, LOCAL_ONLY, &has_exception);
- if (has_exception) return EXCEPTION;
+ Handle<FixedArray> contents;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, contents,
+ JSReceiver::GetKeys(object, JSReceiver::LOCAL_ONLY),
+ EXCEPTION);
for (int i = 0; i < contents->length(); i++) {
Object* key = contents->get(i);
Handle<String> key_handle;
- Handle<Object> property;
+ MaybeHandle<Object> maybe_property;
if (key->IsString()) {
key_handle = Handle<String>(String::cast(key), isolate_);
- property = GetProperty(isolate_, object, key_handle);
+ maybe_property = Object::GetPropertyOrElement(object, key_handle);
} else {
ASSERT(key->IsNumber());
key_handle = factory_->NumberToString(Handle<Object>(key, isolate_));
uint32_t index;
if (key->IsSmi()) {
- property = Object::GetElement(
+ maybe_property = Object::GetElement(
isolate_, object, Smi::cast(key)->value());
} else if (key_handle->AsArrayIndex(&index)) {
- property = Object::GetElement(isolate_, object, index);
+ maybe_property = Object::GetElement(isolate_, object, index);
} else {
- property = GetProperty(isolate_, object, key_handle);
+ maybe_property = Object::GetPropertyOrElement(object, key_handle);
}
}
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate_, property, EXCEPTION);
+ Handle<Object> property;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, property, maybe_property, EXCEPTION);
Result result = SerializeProperty(property, comma, key_handle);
if (!comma && result == SUCCESS) comma = true;
- if (result >= EXCEPTION) return result;
+ if (result == EXCEPTION) return result;
}
}
@@ -731,7 +727,8 @@ void BasicJsonStringifier::Accumulate() {
set_accumulator(factory_->empty_string());
overflowed_ = true;
} else {
- set_accumulator(factory_->NewConsString(accumulator(), current_part_));
+ set_accumulator(factory_->NewConsString(accumulator(),
+ current_part_).ToHandleChecked());
}
}
@@ -742,9 +739,11 @@ void BasicJsonStringifier::Extend() {
part_length_ *= kPartLengthGrowthFactor;
}
if (is_ascii_) {
- current_part_ = factory_->NewRawOneByteString(part_length_);
+ current_part_ =
+ factory_->NewRawOneByteString(part_length_).ToHandleChecked();
} else {
- current_part_ = factory_->NewRawTwoByteString(part_length_);
+ current_part_ =
+ factory_->NewRawTwoByteString(part_length_).ToHandleChecked();
}
ASSERT(!current_part_.is_null());
current_index_ = 0;
@@ -754,7 +753,8 @@ void BasicJsonStringifier::Extend() {
void BasicJsonStringifier::ChangeEncoding() {
ShrinkCurrentPart();
Accumulate();
- current_part_ = factory_->NewRawTwoByteString(part_length_);
+ current_part_ =
+ factory_->NewRawTwoByteString(part_length_).ToHandleChecked();
ASSERT(!current_part_.is_null());
current_index_ = 0;
is_ascii_ = false;
@@ -864,7 +864,7 @@ Vector<const uc16> BasicJsonStringifier::GetCharVector(Handle<String> string) {
void BasicJsonStringifier::SerializeString(Handle<String> object) {
- object = FlattenGetString(object);
+ object = String::Flatten(object);
if (is_ascii_) {
if (object->IsOneByteRepresentationUnderneath()) {
SerializeString_<true, uint8_t>(object);
diff --git a/deps/v8/src/json.js b/deps/v8/src/json.js
index fc4b58deca..93e38b0dba 100644
--- a/deps/v8/src/json.js
+++ b/deps/v8/src/json.js
@@ -1,29 +1,6 @@
// Copyright 2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file relies on the fact that the following declarations have been made
// in runtime.js:
diff --git a/deps/v8/src/jsregexp-inl.h b/deps/v8/src/jsregexp-inl.h
index 3ef07d8c54..34e60fa0ab 100644
--- a/deps/v8/src/jsregexp-inl.h
+++ b/deps/v8/src/jsregexp-inl.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_JSREGEXP_INL_H_
diff --git a/deps/v8/src/jsregexp.cc b/deps/v8/src/jsregexp.cc
index a30fc26ff0..7284c778cb 100644
--- a/deps/v8/src/jsregexp.cc
+++ b/deps/v8/src/jsregexp.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -66,14 +43,13 @@
namespace v8 {
namespace internal {
-Handle<Object> RegExpImpl::CreateRegExpLiteral(Handle<JSFunction> constructor,
- Handle<String> pattern,
- Handle<String> flags,
- bool* has_pending_exception) {
+MaybeHandle<Object> RegExpImpl::CreateRegExpLiteral(
+ Handle<JSFunction> constructor,
+ Handle<String> pattern,
+ Handle<String> flags) {
// Call the construct code with 2 arguments.
Handle<Object> argv[] = { pattern, flags };
- return Execution::New(constructor, ARRAY_SIZE(argv), argv,
- has_pending_exception);
+ return Execution::New(constructor, ARRAY_SIZE(argv), argv);
}
@@ -96,10 +72,12 @@ static JSRegExp::Flags RegExpFlagsFromString(Handle<String> str) {
}
-static inline void ThrowRegExpException(Handle<JSRegExp> re,
- Handle<String> pattern,
- Handle<String> error_text,
- const char* message) {
+MUST_USE_RESULT
+static inline MaybeHandle<Object> ThrowRegExpException(
+ Handle<JSRegExp> re,
+ Handle<String> pattern,
+ Handle<String> error_text,
+ const char* message) {
Isolate* isolate = re->GetIsolate();
Factory* factory = isolate->factory();
Handle<FixedArray> elements = factory->NewFixedArray(2);
@@ -107,7 +85,7 @@ static inline void ThrowRegExpException(Handle<JSRegExp> re,
elements->set(1, *error_text);
Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
Handle<Object> regexp_err = factory->NewSyntaxError(message, array);
- isolate->Throw(*regexp_err);
+ return isolate->Throw<Object>(regexp_err);
}
@@ -168,15 +146,17 @@ static bool HasFewDifferentCharacters(Handle<String> pattern) {
// Generic RegExp methods. Dispatches to implementation specific methods.
-Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
- Handle<String> pattern,
- Handle<String> flag_str) {
+MaybeHandle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
+ Handle<String> pattern,
+ Handle<String> flag_str) {
Isolate* isolate = re->GetIsolate();
Zone zone(isolate);
JSRegExp::Flags flags = RegExpFlagsFromString(flag_str);
CompilationCache* compilation_cache = isolate->compilation_cache();
- Handle<FixedArray> cached = compilation_cache->LookupRegExp(pattern, flags);
- bool in_cache = !cached.is_null();
+ MaybeHandle<FixedArray> maybe_cached =
+ compilation_cache->LookupRegExp(pattern, flags);
+ Handle<FixedArray> cached;
+ bool in_cache = maybe_cached.ToHandle(&cached);
LOG(isolate, RegExpCompileEvent(re, in_cache));
Handle<Object> result;
@@ -184,18 +164,17 @@ Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
re->set_data(*cached);
return re;
}
- pattern = FlattenGetString(pattern);
+ pattern = String::Flatten(pattern);
PostponeInterruptsScope postpone(isolate);
RegExpCompileData parse_result;
FlatStringReader reader(isolate, pattern);
if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(),
&parse_result, &zone)) {
// Throw an exception if we fail to parse the pattern.
- ThrowRegExpException(re,
- pattern,
- parse_result.error,
- "malformed_regexp");
- return Handle<Object>::null();
+ return ThrowRegExpException(re,
+ pattern,
+ parse_result.error,
+ "malformed_regexp");
}
bool has_been_compiled = false;
@@ -211,8 +190,11 @@ Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
parse_result.capture_count == 0) {
RegExpAtom* atom = parse_result.tree->AsAtom();
Vector<const uc16> atom_pattern = atom->data();
- Handle<String> atom_string =
- isolate->factory()->NewStringFromTwoByte(atom_pattern);
+ Handle<String> atom_string;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, atom_string,
+ isolate->factory()->NewStringFromTwoByte(atom_pattern),
+ Object);
if (!HasFewDifferentCharacters(atom_string)) {
AtomCompile(re, pattern, flags, atom_string);
has_been_compiled = true;
@@ -231,23 +213,19 @@ Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
}
-Handle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp,
- Handle<String> subject,
- int index,
- Handle<JSArray> last_match_info) {
+MaybeHandle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp,
+ Handle<String> subject,
+ int index,
+ Handle<JSArray> last_match_info) {
switch (regexp->TypeTag()) {
case JSRegExp::ATOM:
return AtomExec(regexp, subject, index, last_match_info);
case JSRegExp::IRREGEXP: {
- Handle<Object> result =
- IrregexpExec(regexp, subject, index, last_match_info);
- ASSERT(!result.is_null() ||
- regexp->GetIsolate()->has_pending_exception());
- return result;
+ return IrregexpExec(regexp, subject, index, last_match_info);
}
default:
UNREACHABLE();
- return Handle<Object>::null();
+ return MaybeHandle<Object>();
}
}
@@ -290,7 +268,7 @@ int RegExpImpl::AtomExecRaw(Handle<JSRegExp> regexp,
ASSERT(0 <= index);
ASSERT(index <= subject->length());
- if (!subject->IsFlat()) FlattenString(subject);
+ subject = String::Flatten(subject);
DisallowHeapAllocation no_gc; // ensure vectors stay valid
String* needle = String::cast(regexp->DataAt(JSRegExp::kAtomPatternIndex));
@@ -439,7 +417,7 @@ bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
JSRegExp::Flags flags = re->GetFlags();
Handle<String> pattern(re->Pattern());
- if (!pattern->IsFlat()) FlattenString(pattern);
+ pattern = String::Flatten(pattern);
RegExpCompileData compile_data;
FlatStringReader reader(isolate, pattern);
if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(),
@@ -447,10 +425,10 @@ bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
&zone)) {
// Throw an exception if we fail to parse the pattern.
// THIS SHOULD NOT HAPPEN. We already pre-parsed it successfully once.
- ThrowRegExpException(re,
- pattern,
- compile_data.error,
- "malformed_regexp");
+ USE(ThrowRegExpException(re,
+ pattern,
+ compile_data.error,
+ "malformed_regexp"));
return false;
}
RegExpEngine::CompilationResult result =
@@ -464,9 +442,8 @@ bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
&zone);
if (result.error_message != NULL) {
// Unable to compile regexp.
- Handle<String> error_message =
- isolate->factory()->NewStringFromUtf8(CStrVector(result.error_message));
- ASSERT(!error_message.is_null());
+ Handle<String> error_message = isolate->factory()->NewStringFromUtf8(
+ CStrVector(result.error_message)).ToHandleChecked();
CreateRegExpErrorObjectAndThrow(re, is_ascii, error_message, isolate);
return false;
}
@@ -528,7 +505,7 @@ void RegExpImpl::IrregexpInitialize(Handle<JSRegExp> re,
int RegExpImpl::IrregexpPrepare(Handle<JSRegExp> regexp,
Handle<String> subject) {
- if (!subject->IsFlat()) FlattenString(subject);
+ subject = String::Flatten(subject);
// Check the asciiness of the underlying storage.
bool is_ascii = subject->IsOneByteRepresentationUnderneath();
@@ -637,10 +614,10 @@ int RegExpImpl::IrregexpExecRaw(Handle<JSRegExp> regexp,
}
-Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp,
- Handle<String> subject,
- int previous_index,
- Handle<JSArray> last_match_info) {
+MaybeHandle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp,
+ Handle<String> subject,
+ int previous_index,
+ Handle<JSArray> last_match_info) {
Isolate* isolate = regexp->GetIsolate();
ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
@@ -656,7 +633,7 @@ Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp,
if (required_registers < 0) {
// Compiling failed with an exception.
ASSERT(isolate->has_pending_exception());
- return Handle<Object>::null();
+ return MaybeHandle<Object>();
}
int32_t* output_registers = NULL;
@@ -678,7 +655,7 @@ Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp,
}
if (res == RE_EXCEPTION) {
ASSERT(isolate->has_pending_exception());
- return Handle<Object>::null();
+ return MaybeHandle<Object>();
}
ASSERT(res == RE_FAILURE);
return isolate->factory()->null_value();
@@ -6015,7 +5992,7 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(
// Sample some characters from the middle of the string.
static const int kSampleSize = 128;
- FlattenString(sample_subject);
+ sample_subject = String::Flatten(sample_subject);
int chars_sampled = 0;
int half_way = (sample_subject->length() - kSampleSize) / 2;
for (int i = Max(0, half_way);
diff --git a/deps/v8/src/jsregexp.h b/deps/v8/src/jsregexp.h
index dfd415d5af..5366d6e132 100644
--- a/deps/v8/src/jsregexp.h
+++ b/deps/v8/src/jsregexp.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_JSREGEXP_H_
#define V8_JSREGEXP_H_
@@ -55,10 +32,10 @@ class RegExpImpl {
// Creates a regular expression literal in the old space.
// This function calls the garbage collector if necessary.
- static Handle<Object> CreateRegExpLiteral(Handle<JSFunction> constructor,
- Handle<String> pattern,
- Handle<String> flags,
- bool* has_pending_exception);
+ MUST_USE_RESULT static MaybeHandle<Object> CreateRegExpLiteral(
+ Handle<JSFunction> constructor,
+ Handle<String> pattern,
+ Handle<String> flags);
// Returns a string representation of a regular expression.
// Implements RegExp.prototype.toString, see ECMA-262 section 15.10.6.4.
@@ -69,16 +46,18 @@ class RegExpImpl {
// generic data and choice of implementation - as well as what
// the implementation wants to store in the data field.
// Returns false if compilation fails.
- static Handle<Object> Compile(Handle<JSRegExp> re,
- Handle<String> pattern,
- Handle<String> flags);
+ MUST_USE_RESULT static MaybeHandle<Object> Compile(
+ Handle<JSRegExp> re,
+ Handle<String> pattern,
+ Handle<String> flags);
// See ECMA-262 section 15.10.6.2.
// This function calls the garbage collector if necessary.
- static Handle<Object> Exec(Handle<JSRegExp> regexp,
- Handle<String> subject,
- int index,
- Handle<JSArray> lastMatchInfo);
+ MUST_USE_RESULT static MaybeHandle<Object> Exec(
+ Handle<JSRegExp> regexp,
+ Handle<String> subject,
+ int index,
+ Handle<JSArray> lastMatchInfo);
// Prepares a JSRegExp object with Irregexp-specific data.
static void IrregexpInitialize(Handle<JSRegExp> re,
@@ -133,10 +112,11 @@ class RegExpImpl {
// On a successful match, the result is a JSArray containing
// captured positions. On a failure, the result is the null value.
// Returns an empty handle in case of an exception.
- static Handle<Object> IrregexpExec(Handle<JSRegExp> regexp,
- Handle<String> subject,
- int index,
- Handle<JSArray> lastMatchInfo);
+ MUST_USE_RESULT static MaybeHandle<Object> IrregexpExec(
+ Handle<JSRegExp> regexp,
+ Handle<String> subject,
+ int index,
+ Handle<JSArray> lastMatchInfo);
// Set last match info. If match is NULL, then setting captures is omitted.
static Handle<JSArray> SetLastMatchInfo(Handle<JSArray> last_match_info,
diff --git a/deps/v8/src/lazy-instance.h b/deps/v8/src/lazy-instance.h
index fc03f4d126..b760f1fb67 100644
--- a/deps/v8/src/lazy-instance.h
+++ b/deps/v8/src/lazy-instance.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// The LazyInstance<Type, Traits> class manages a single instance of Type,
// which will be lazily created on the first time it's accessed. This class is
@@ -66,8 +43,8 @@
// LAZY_INSTANCE_INITIALIZER;
//
// WARNINGS:
-// - This implementation of LazyInstance is NOT THREAD-SAFE by default. See
-// ThreadSafeInitOnceTrait declared below for that.
+// - This implementation of LazyInstance IS THREAD-SAFE by default. See
+// SingleThreadInitOnceTrait if you don't care about thread safety.
// - Lazy initialization comes with a cost. Make sure that you don't use it on
// critical path. Consider adding your initialization code to a function
// which is explicitly called once.
@@ -227,7 +204,7 @@ struct LazyInstanceImpl {
template <typename T,
typename CreateTrait = DefaultConstructTrait<T>,
- typename InitOnceTrait = SingleThreadInitOnceTrait,
+ typename InitOnceTrait = ThreadSafeInitOnceTrait,
typename DestroyTrait = LeakyInstanceTrait<T> >
struct LazyStaticInstance {
typedef LazyInstanceImpl<T, StaticallyAllocatedInstanceTrait<T>,
@@ -237,7 +214,7 @@ struct LazyStaticInstance {
template <typename T,
typename CreateTrait = DefaultConstructTrait<T>,
- typename InitOnceTrait = SingleThreadInitOnceTrait,
+ typename InitOnceTrait = ThreadSafeInitOnceTrait,
typename DestroyTrait = LeakyInstanceTrait<T> >
struct LazyInstance {
// A LazyInstance is a LazyStaticInstance.
@@ -248,7 +225,7 @@ struct LazyInstance {
template <typename T,
typename CreateTrait = DefaultCreateTrait<T>,
- typename InitOnceTrait = SingleThreadInitOnceTrait,
+ typename InitOnceTrait = ThreadSafeInitOnceTrait,
typename DestroyTrait = LeakyInstanceTrait<T> >
struct LazyDynamicInstance {
typedef LazyInstanceImpl<T, DynamicallyAllocatedInstanceTrait<T>,
diff --git a/deps/v8/src/libplatform/default-platform.cc b/deps/v8/src/libplatform/default-platform.cc
index 1e21ca4e82..6ff8830fb2 100644
--- a/deps/v8/src/libplatform/default-platform.cc
+++ b/deps/v8/src/libplatform/default-platform.cc
@@ -1,32 +1,10 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "default-platform.h"
+#include <algorithm>
#include <queue>
// TODO(jochen): We should have our own version of checks.h.
@@ -39,6 +17,9 @@ namespace v8 {
namespace internal {
+const int DefaultPlatform::kMaxThreadPoolSize = 4;
+
+
DefaultPlatform::DefaultPlatform()
: initialized_(false), thread_pool_size_(0) {}
@@ -60,7 +41,8 @@ void DefaultPlatform::SetThreadPoolSize(int thread_pool_size) {
ASSERT(thread_pool_size >= 0);
if (thread_pool_size < 1)
thread_pool_size = CPU::NumberOfProcessorsOnline();
- thread_pool_size_ = Max(Min(thread_pool_size, kMaxThreadPoolSize), 1);
+ thread_pool_size_ =
+ std::max(std::min(thread_pool_size, kMaxThreadPoolSize), 1);
}
diff --git a/deps/v8/src/libplatform/default-platform.h b/deps/v8/src/libplatform/default-platform.h
index 5c48832344..f887eb32e8 100644
--- a/deps/v8/src/libplatform/default-platform.h
+++ b/deps/v8/src/libplatform/default-platform.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_LIBPLATFORM_DEFAULT_PLATFORM_H_
#define V8_LIBPLATFORM_DEFAULT_PLATFORM_H_
@@ -31,8 +8,7 @@
#include <vector>
#include "../../include/v8-platform.h"
-// TODO(jochen): We should have our own version of globals.h.
-#include "../globals.h"
+#include "../base/macros.h"
#include "../platform/mutex.h"
#include "task-queue.h"
@@ -59,7 +35,7 @@ class DefaultPlatform : public Platform {
Task *task) V8_OVERRIDE;
private:
- static const int kMaxThreadPoolSize = 4;
+ static const int kMaxThreadPoolSize;
Mutex lock_;
bool initialized_;
diff --git a/deps/v8/src/libplatform/task-queue.cc b/deps/v8/src/libplatform/task-queue.cc
index 1ea31eb26e..37cf1353e5 100644
--- a/deps/v8/src/libplatform/task-queue.cc
+++ b/deps/v8/src/libplatform/task-queue.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "task-queue.h"
diff --git a/deps/v8/src/libplatform/task-queue.h b/deps/v8/src/libplatform/task-queue.h
index a3182d3531..8b9137b032 100644
--- a/deps/v8/src/libplatform/task-queue.h
+++ b/deps/v8/src/libplatform/task-queue.h
@@ -1,37 +1,13 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_LIBPLATFORM_TASK_QUEUE_H_
#define V8_LIBPLATFORM_TASK_QUEUE_H_
#include <queue>
-// TODO(jochen): We should have our own version of globals.h.
-#include "../globals.h"
+#include "../base/macros.h"
#include "../platform/mutex.h"
#include "../platform/semaphore.h"
diff --git a/deps/v8/src/libplatform/worker-thread.cc b/deps/v8/src/libplatform/worker-thread.cc
index cca8a9719a..e7d8ec7634 100644
--- a/deps/v8/src/libplatform/worker-thread.cc
+++ b/deps/v8/src/libplatform/worker-thread.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "worker-thread.h"
diff --git a/deps/v8/src/libplatform/worker-thread.h b/deps/v8/src/libplatform/worker-thread.h
index f0b9019f59..b9d7fdabe1 100644
--- a/deps/v8/src/libplatform/worker-thread.h
+++ b/deps/v8/src/libplatform/worker-thread.h
@@ -1,37 +1,13 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_LIBPLATFORM_WORKER_THREAD_H_
#define V8_LIBPLATFORM_WORKER_THREAD_H_
#include <queue>
-// TODO(jochen): We should have our own version of globals.h.
-#include "../globals.h"
+#include "../base/macros.h"
#include "../platform.h"
namespace v8 {
diff --git a/deps/v8/src/list-inl.h b/deps/v8/src/list-inl.h
index a80aa67434..4a18d98205 100644
--- a/deps/v8/src/list-inl.h
+++ b/deps/v8/src/list-inl.h
@@ -1,29 +1,6 @@
// Copyright 2006-2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_LIST_INL_H_
#define V8_LIST_INL_H_
diff --git a/deps/v8/src/list.h b/deps/v8/src/list.h
index 71aa821959..1029f493f1 100644
--- a/deps/v8/src/list.h
+++ b/deps/v8/src/list.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_LIST_H_
#define V8_LIST_H_
diff --git a/deps/v8/src/lithium-allocator-inl.h b/deps/v8/src/lithium-allocator-inl.h
index 7c0cba7fba..1b9de0eede 100644
--- a/deps/v8/src/lithium-allocator-inl.h
+++ b/deps/v8/src/lithium-allocator-inl.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_LITHIUM_ALLOCATOR_INL_H_
#define V8_LITHIUM_ALLOCATOR_INL_H_
diff --git a/deps/v8/src/lithium-allocator.cc b/deps/v8/src/lithium-allocator.cc
index 9987161d4d..c6e52ed824 100644
--- a/deps/v8/src/lithium-allocator.cc
+++ b/deps/v8/src/lithium-allocator.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
#include "lithium-allocator-inl.h"
@@ -69,7 +46,8 @@ UsePosition::UsePosition(LifetimePosition pos,
register_beneficial_(true) {
if (operand_ != NULL && operand_->IsUnallocated()) {
LUnallocated* unalloc = LUnallocated::cast(operand_);
- requires_reg_ = unalloc->HasRegisterPolicy();
+ requires_reg_ = unalloc->HasRegisterPolicy() ||
+ unalloc->HasDoubleRegisterPolicy();
register_beneficial_ = !unalloc->HasAnyPolicy();
}
ASSERT(pos_.IsValid());
@@ -986,7 +964,7 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) {
}
}
- if (instr->ClobbersDoubleRegisters()) {
+ if (instr->ClobbersDoubleRegisters(isolate())) {
for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) {
if (output == NULL || !output->IsDoubleRegister() ||
output->index() != i) {
@@ -1028,6 +1006,15 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) {
}
Use(block_start_position, curr_position.InstructionEnd(), temp, NULL);
Define(curr_position, temp, NULL);
+
+ if (temp->IsUnallocated()) {
+ LUnallocated* temp_unalloc = LUnallocated::cast(temp);
+ if (temp_unalloc->HasDoubleRegisterPolicy()) {
+ double_artificial_registers_.Add(
+ temp_unalloc->virtual_register() - first_artificial_register_,
+ zone());
+ }
+ }
}
}
}
@@ -1118,7 +1105,6 @@ bool LAllocator::Allocate(LChunk* chunk) {
void LAllocator::MeetRegisterConstraints() {
LAllocatorPhase phase("L_Register constraints", this);
- first_artificial_register_ = next_virtual_register_;
const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
for (int i = 0; i < blocks->length(); ++i) {
HBasicBlock* block = blocks->at(i);
diff --git a/deps/v8/src/lithium-allocator.h b/deps/v8/src/lithium-allocator.h
index 8a1476a04b..83ba9afb68 100644
--- a/deps/v8/src/lithium-allocator.h
+++ b/deps/v8/src/lithium-allocator.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_LITHIUM_ALLOCATOR_H_
#define V8_LITHIUM_ALLOCATOR_H_
diff --git a/deps/v8/src/lithium-codegen.cc b/deps/v8/src/lithium-codegen.cc
index be0ff8371a..0d841b7e80 100644
--- a/deps/v8/src/lithium-codegen.cc
+++ b/deps/v8/src/lithium-codegen.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -122,6 +99,30 @@ bool LCodeGenBase::GenerateBody() {
}
+void LCodeGenBase::CheckEnvironmentUsage() {
+#ifdef DEBUG
+ bool dead_block = false;
+ for (int i = 0; i < instructions_->length(); i++) {
+ LInstruction* instr = instructions_->at(i);
+ HValue* hval = instr->hydrogen_value();
+ if (instr->IsLabel()) dead_block = LLabel::cast(instr)->HasReplacement();
+ if (dead_block || !hval->block()->IsReachable()) continue;
+
+ HInstruction* hinstr = HInstruction::cast(hval);
+ if (!hinstr->CanDeoptimize() && instr->HasEnvironment()) {
+ V8_Fatal(__FILE__, __LINE__, "CanDeoptimize is wrong for %s (%s)\n",
+ hinstr->Mnemonic(), instr->Mnemonic());
+ }
+
+ if (instr->HasEnvironment() && !instr->environment()->has_been_used()) {
+ V8_Fatal(__FILE__, __LINE__, "unused environment for %s (%s)\n",
+ hinstr->Mnemonic(), instr->Mnemonic());
+ }
+ }
+#endif
+}
+
+
void LCodeGenBase::Comment(const char* format, ...) {
if (!FLAG_code_comments) return;
char buffer[4 * KB];
@@ -149,6 +150,17 @@ int LCodeGenBase::GetNextEmittedBlock() const {
}
+static void AddWeakObjectToCodeDependency(Isolate* isolate,
+ Handle<Object> object,
+ Handle<Code> code) {
+ Heap* heap = isolate->heap();
+ heap->EnsureWeakObjectToCodeTable();
+ Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object));
+ dep = DependentCode::Insert(dep, DependentCode::kWeakCodeGroup, code);
+ heap->AddWeakObjectToCodeDependency(object, dep);
+}
+
+
void LCodeGenBase::RegisterWeakObjectsInOptimizedCode(Handle<Code> code) {
ASSERT(code->is_optimized_code());
ZoneList<Handle<Map> > maps(1, zone());
@@ -176,6 +188,10 @@ void LCodeGenBase::RegisterWeakObjectsInOptimizedCode(Handle<Code> code) {
}
}
}
+ if (FLAG_enable_ool_constant_pool) {
+ code->constant_pool()->set_weak_object_state(
+ ConstantPoolArray::WEAK_OBJECTS_IN_OPTIMIZED_CODE);
+ }
#ifdef VERIFY_HEAP
// This disables verification of weak embedded objects after full GC.
// AddDependentCode can cause a GC, which would observe the state where
@@ -183,15 +199,32 @@ void LCodeGenBase::RegisterWeakObjectsInOptimizedCode(Handle<Code> code) {
NoWeakObjectVerificationScope disable_verification_of_embedded_objects;
#endif
for (int i = 0; i < maps.length(); i++) {
- maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code);
+ Map::AddDependentCode(maps.at(i), DependentCode::kWeakCodeGroup, code);
}
for (int i = 0; i < objects.length(); i++) {
- AddWeakObjectToCodeDependency(isolate()->heap(), objects.at(i), code);
+ AddWeakObjectToCodeDependency(isolate(), objects.at(i), code);
}
for (int i = 0; i < cells.length(); i++) {
- AddWeakObjectToCodeDependency(isolate()->heap(), cells.at(i), code);
+ AddWeakObjectToCodeDependency(isolate(), cells.at(i), code);
}
}
+void LCodeGenBase::Abort(BailoutReason reason) {
+ info()->set_bailout_reason(reason);
+ status_ = ABORTED;
+}
+
+
+void LCodeGenBase::AddDeprecationDependency(Handle<Map> map) {
+ if (map->is_deprecated()) return Abort(kMapBecameDeprecated);
+ chunk_->AddDeprecationDependency(map);
+}
+
+
+void LCodeGenBase::AddStabilityDependency(Handle<Map> map) {
+ if (!map->is_stable()) return Abort(kMapBecameUnstable);
+ chunk_->AddStabilityDependency(map);
+}
+
} } // namespace v8::internal
diff --git a/deps/v8/src/lithium-codegen.h b/deps/v8/src/lithium-codegen.h
index 3e8d471ea7..28a5ab16e0 100644
--- a/deps/v8/src/lithium-codegen.h
+++ b/deps/v8/src/lithium-codegen.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_LITHIUM_CODEGEN_H_
#define V8_LITHIUM_CODEGEN_H_
@@ -68,6 +45,11 @@ class LCodeGenBase BASE_EMBEDDED {
void RegisterWeakObjectsInOptimizedCode(Handle<Code> code);
+ // Check that an environment assigned via AssignEnvironment is actually being
+ // used. Redundant assignments keep things alive longer than necessary, and
+ // consequently lead to worse code, so it's important to minimize this.
+ void CheckEnvironmentUsage();
+
protected:
enum Status {
UNUSED,
@@ -90,6 +72,12 @@ class LCodeGenBase BASE_EMBEDDED {
bool is_generating() const { return status_ == GENERATING; }
bool is_done() const { return status_ == DONE; }
bool is_aborted() const { return status_ == ABORTED; }
+
+ void Abort(BailoutReason reason);
+
+ // Methods for code dependencies.
+ void AddDeprecationDependency(Handle<Map> map);
+ void AddStabilityDependency(Handle<Map> map);
};
diff --git a/deps/v8/src/lithium.cc b/deps/v8/src/lithium.cc
index 8753ff14aa..2265353f47 100644
--- a/deps/v8/src/lithium.cc
+++ b/deps/v8/src/lithium.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
#include "lithium.h"
@@ -85,6 +62,9 @@ void LOperand::PrintTo(StringStream* stream) {
case LUnallocated::MUST_HAVE_REGISTER:
stream->Add("(R)");
break;
+ case LUnallocated::MUST_HAVE_DOUBLE_REGISTER:
+ stream->Add("(D)");
+ break;
case LUnallocated::WRITABLE_REGISTER:
stream->Add("(WR)");
break;
@@ -256,7 +236,9 @@ LChunk::LChunk(CompilationInfo* info, HGraph* graph)
graph_(graph),
instructions_(32, graph->zone()),
pointer_maps_(8, graph->zone()),
- inlined_closures_(1, graph->zone()) {
+ inlined_closures_(1, graph->zone()),
+ deprecation_dependencies_(MapLess(), MapAllocator(graph->zone())),
+ stability_dependencies_(MapLess(), MapAllocator(graph->zone())) {
}
@@ -395,6 +377,27 @@ Representation LChunk::LookupLiteralRepresentation(
}
+void LChunk::CommitDependencies(Handle<Code> code) const {
+ for (MapSet::const_iterator it = deprecation_dependencies_.begin(),
+ iend = deprecation_dependencies_.end(); it != iend; ++it) {
+ Handle<Map> map = *it;
+ ASSERT(!map->is_deprecated());
+ ASSERT(map->CanBeDeprecated());
+ Map::AddDependentCode(map, DependentCode::kTransitionGroup, code);
+ }
+
+ for (MapSet::const_iterator it = stability_dependencies_.begin(),
+ iend = stability_dependencies_.end(); it != iend; ++it) {
+ Handle<Map> map = *it;
+ ASSERT(map->is_stable());
+ ASSERT(map->CanTransition());
+ Map::AddDependentCode(map, DependentCode::kPrototypeCheckGroup, code);
+ }
+
+ info_->CommitDependencies(code);
+}
+
+
LChunk* LChunk::NewChunk(HGraph* graph) {
DisallowHandleAllocation no_handles;
DisallowHeapAllocation no_gc;
@@ -432,11 +435,13 @@ Handle<Code> LChunk::Codegen() {
MarkEmptyBlocks();
if (generator.GenerateCode()) {
+ generator.CheckEnvironmentUsage();
CodeGenerator::MakeCodePrologue(info(), "optimized");
Code::Flags flags = info()->flags();
Handle<Code> code =
CodeGenerator::MakeCodeEpilogue(&assembler, flags, info());
generator.FinishCode(code);
+ CommitDependencies(code);
code->set_is_crankshafted(true);
void* jit_handler_data =
assembler.positions_recorder()->DetachJITHandlerData();
diff --git a/deps/v8/src/lithium.h b/deps/v8/src/lithium.h
index 8ae5b879dc..650bae6923 100644
--- a/deps/v8/src/lithium.h
+++ b/deps/v8/src/lithium.h
@@ -1,36 +1,16 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_LITHIUM_H_
#define V8_LITHIUM_H_
+#include <set>
+
#include "allocation.h"
#include "hydrogen.h"
#include "safepoint-table.h"
+#include "zone-allocator.h"
namespace v8 {
namespace internal {
@@ -101,6 +81,7 @@ class LUnallocated : public LOperand {
FIXED_REGISTER,
FIXED_DOUBLE_REGISTER,
MUST_HAVE_REGISTER,
+ MUST_HAVE_DOUBLE_REGISTER,
WRITABLE_REGISTER,
SAME_AS_FIRST_INPUT
};
@@ -210,6 +191,10 @@ class LUnallocated : public LOperand {
extended_policy() == WRITABLE_REGISTER ||
extended_policy() == MUST_HAVE_REGISTER);
}
+ bool HasDoubleRegisterPolicy() const {
+ return basic_policy() == EXTENDED_POLICY &&
+ extended_policy() == MUST_HAVE_DOUBLE_REGISTER;
+ }
bool HasSameAsInputPolicy() const {
return basic_policy() == EXTENDED_POLICY &&
extended_policy() == SAME_AS_FIRST_INPUT;
@@ -426,7 +411,8 @@ class LEnvironment V8_FINAL : public ZoneObject {
object_mapping_(0, zone),
outer_(outer),
entry_(entry),
- zone_(zone) { }
+ zone_(zone),
+ has_been_used_(false) { }
Handle<JSFunction> closure() const { return closure_; }
FrameType frame_type() const { return frame_type_; }
@@ -442,6 +428,9 @@ class LEnvironment V8_FINAL : public ZoneObject {
HEnterInlined* entry() { return entry_; }
Zone* zone() const { return zone_; }
+ bool has_been_used() const { return has_been_used_; }
+ void set_has_been_used() { has_been_used_ = true; }
+
void AddValue(LOperand* operand,
Representation representation,
bool is_uint32) {
@@ -541,6 +530,7 @@ class LEnvironment V8_FINAL : public ZoneObject {
LEnvironment* outer_;
HEnterInlined* entry_;
Zone* zone_;
+ bool has_been_used_;
};
@@ -660,6 +650,20 @@ class LChunk : public ZoneObject {
inlined_closures_.Add(closure, zone());
}
+ void AddDeprecationDependency(Handle<Map> map) {
+ ASSERT(!map->is_deprecated());
+ if (!map->CanBeDeprecated()) return;
+ ASSERT(!info_->IsStub());
+ deprecation_dependencies_.insert(map);
+ }
+
+ void AddStabilityDependency(Handle<Map> map) {
+ ASSERT(map->is_stable());
+ if (!map->CanTransition()) return;
+ ASSERT(!info_->IsStub());
+ stability_dependencies_.insert(map);
+ }
+
Zone* zone() const { return info_->zone(); }
Handle<Code> Codegen();
@@ -675,12 +679,20 @@ class LChunk : public ZoneObject {
int spill_slot_count_;
private:
+ typedef std::less<Handle<Map> > MapLess;
+ typedef zone_allocator<Handle<Map> > MapAllocator;
+ typedef std::set<Handle<Map>, MapLess, MapAllocator> MapSet;
+
+ void CommitDependencies(Handle<Code> code) const;
+
CompilationInfo* info_;
HGraph* const graph_;
BitVector* allocated_double_registers_;
ZoneList<LInstruction*> instructions_;
ZoneList<LPointerMap*> pointer_maps_;
ZoneList<Handle<JSFunction> > inlined_closures_;
+ MapSet deprecation_dependencies_;
+ MapSet stability_dependencies_;
};
diff --git a/deps/v8/src/liveedit-debugger.js b/deps/v8/src/liveedit-debugger.js
index 4618eda366..021a4f052a 100644
--- a/deps/v8/src/liveedit-debugger.js
+++ b/deps/v8/src/liveedit-debugger.js
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// LiveEdit feature implementation. The script should be executed after
// debug-debugger.js.
diff --git a/deps/v8/src/liveedit.cc b/deps/v8/src/liveedit.cc
index 5eae1073a4..e6bb4b29a6 100644
--- a/deps/v8/src/liveedit.cc
+++ b/deps/v8/src/liveedit.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -45,20 +22,13 @@
namespace v8 {
namespace internal {
-
-#ifdef ENABLE_DEBUGGER_SUPPORT
-
-
void SetElementSloppy(Handle<JSObject> object,
uint32_t index,
Handle<Object> value) {
// Ignore return value from SetElement. It can only be a failure if there
// are element setters causing exceptions and the debugger context has none
// of these.
- Handle<Object> no_failure =
- JSObject::SetElement(object, index, value, NONE, SLOPPY);
- ASSERT(!no_failure.is_null());
- USE(no_failure);
+ JSObject::SetElement(object, index, value, NONE, SLOPPY).Assert();
}
@@ -434,7 +404,7 @@ class TokensCompareOutput : public Comparator::Output {
class LineEndsWrapper {
public:
explicit LineEndsWrapper(Handle<String> string)
- : ends_array_(CalculateLineEnds(string, false)),
+ : ends_array_(String::CalculateLineEnds(string, false)),
string_len_(string->length()) {
}
int length() {
@@ -585,8 +555,8 @@ class TokenizingLineArrayCompareOutput : public SubrangableOutput {
Handle<JSArray> LiveEdit::CompareStrings(Handle<String> s1,
Handle<String> s2) {
- s1 = FlattenGetString(s1);
- s2 = FlattenGetString(s2);
+ s1 = String::Flatten(s1);
+ s2 = String::Flatten(s2);
LineEndsWrapper line_ends1(s1);
LineEndsWrapper line_ends2(s2);
@@ -635,168 +605,94 @@ static int GetArrayLength(Handle<JSArray> array) {
}
-// Simple helper class that creates more or less typed structures over
-// JSArray object. This is an adhoc method of passing structures from C++
-// to JavaScript.
-template<typename S>
-class JSArrayBasedStruct {
- public:
- static S Create(Isolate* isolate) {
- Factory* factory = isolate->factory();
- Handle<JSArray> array = factory->NewJSArray(S::kSize_);
- return S(array);
- }
- static S cast(Object* object) {
- JSArray* array = JSArray::cast(object);
- Handle<JSArray> array_handle(array);
- return S(array_handle);
- }
- explicit JSArrayBasedStruct(Handle<JSArray> array) : array_(array) {
- }
- Handle<JSArray> GetJSArray() {
- return array_;
- }
- Isolate* isolate() const {
- return array_->GetIsolate();
- }
+void FunctionInfoWrapper::SetInitialProperties(Handle<String> name,
+ int start_position,
+ int end_position,
+ int param_num,
+ int literal_count,
+ int slot_count,
+ int parent_index) {
+ HandleScope scope(isolate());
+ this->SetField(kFunctionNameOffset_, name);
+ this->SetSmiValueField(kStartPositionOffset_, start_position);
+ this->SetSmiValueField(kEndPositionOffset_, end_position);
+ this->SetSmiValueField(kParamNumOffset_, param_num);
+ this->SetSmiValueField(kLiteralNumOffset_, literal_count);
+ this->SetSmiValueField(kSlotNumOffset_, slot_count);
+ this->SetSmiValueField(kParentIndexOffset_, parent_index);
+}
- protected:
- void SetField(int field_position, Handle<Object> value) {
- SetElementSloppy(array_, field_position, value);
- }
- void SetSmiValueField(int field_position, int value) {
- SetElementSloppy(array_,
- field_position,
- Handle<Smi>(Smi::FromInt(value), isolate()));
- }
- Handle<Object> GetField(int field_position) {
- return Object::GetElementNoExceptionThrown(
- isolate(), array_, field_position);
- }
- int GetSmiValueField(int field_position) {
- Handle<Object> res = GetField(field_position);
- return Handle<Smi>::cast(res)->value();
- }
- private:
- Handle<JSArray> array_;
-};
+void FunctionInfoWrapper::SetFunctionCode(Handle<Code> function_code,
+ Handle<HeapObject> code_scope_info) {
+ Handle<JSValue> code_wrapper = WrapInJSValue(function_code);
+ this->SetField(kCodeOffset_, code_wrapper);
+ Handle<JSValue> scope_wrapper = WrapInJSValue(code_scope_info);
+ this->SetField(kCodeScopeInfoOffset_, scope_wrapper);
+}
-// Represents some function compilation details. This structure will be used
-// from JavaScript. It contains Code object, which is kept wrapped
-// into a BlindReference for sanitizing reasons.
-class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
- public:
- explicit FunctionInfoWrapper(Handle<JSArray> array)
- : JSArrayBasedStruct<FunctionInfoWrapper>(array) {
- }
- void SetInitialProperties(Handle<String> name, int start_position,
- int end_position, int param_num,
- int literal_count, int parent_index) {
- HandleScope scope(isolate());
- this->SetField(kFunctionNameOffset_, name);
- this->SetSmiValueField(kStartPositionOffset_, start_position);
- this->SetSmiValueField(kEndPositionOffset_, end_position);
- this->SetSmiValueField(kParamNumOffset_, param_num);
- this->SetSmiValueField(kLiteralNumOffset_, literal_count);
- this->SetSmiValueField(kParentIndexOffset_, parent_index);
- }
- void SetFunctionCode(Handle<Code> function_code,
- Handle<HeapObject> code_scope_info) {
- Handle<JSValue> code_wrapper = WrapInJSValue(function_code);
- this->SetField(kCodeOffset_, code_wrapper);
- Handle<JSValue> scope_wrapper = WrapInJSValue(code_scope_info);
- this->SetField(kCodeScopeInfoOffset_, scope_wrapper);
- }
- void SetFunctionScopeInfo(Handle<Object> scope_info_array) {
- this->SetField(kFunctionScopeInfoOffset_, scope_info_array);
- }
- void SetSharedFunctionInfo(Handle<SharedFunctionInfo> info) {
- Handle<JSValue> info_holder = WrapInJSValue(info);
- this->SetField(kSharedFunctionInfoOffset_, info_holder);
- }
- int GetLiteralCount() {
- return this->GetSmiValueField(kLiteralNumOffset_);
- }
- int GetParentIndex() {
- return this->GetSmiValueField(kParentIndexOffset_);
- }
- Handle<Code> GetFunctionCode() {
- Handle<Object> element = this->GetField(kCodeOffset_);
+void FunctionInfoWrapper::SetSharedFunctionInfo(
+ Handle<SharedFunctionInfo> info) {
+ Handle<JSValue> info_holder = WrapInJSValue(info);
+ this->SetField(kSharedFunctionInfoOffset_, info_holder);
+}
+
+
+Handle<Code> FunctionInfoWrapper::GetFunctionCode() {
+ Handle<Object> element = this->GetField(kCodeOffset_);
+ Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
+ Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
+ CHECK(raw_result->IsCode());
+ return Handle<Code>::cast(raw_result);
+}
+
+
+Handle<FixedArray> FunctionInfoWrapper::GetFeedbackVector() {
+ Handle<Object> element = this->GetField(kSharedFunctionInfoOffset_);
+ Handle<FixedArray> result;
+ if (element->IsJSValue()) {
Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
- CHECK(raw_result->IsCode());
- return Handle<Code>::cast(raw_result);
- }
- Handle<Object> GetCodeScopeInfo() {
- Handle<Object> element = this->GetField(kCodeScopeInfoOffset_);
- return UnwrapJSValue(Handle<JSValue>::cast(element));
- }
- int GetStartPosition() {
- return this->GetSmiValueField(kStartPositionOffset_);
- }
- int GetEndPosition() {
- return this->GetSmiValueField(kEndPositionOffset_);
+ Handle<SharedFunctionInfo> shared =
+ Handle<SharedFunctionInfo>::cast(raw_result);
+ result = Handle<FixedArray>(shared->feedback_vector(), isolate());
+ CHECK_EQ(result->length(), GetSlotCount());
+ } else {
+ // Scripts may never have a SharedFunctionInfo created, so
+ // create a type feedback vector here.
+ int slot_count = GetSlotCount();
+ result = isolate()->factory()->NewTypeFeedbackVector(slot_count);
}
-
- private:
- static const int kFunctionNameOffset_ = 0;
- static const int kStartPositionOffset_ = 1;
- static const int kEndPositionOffset_ = 2;
- static const int kParamNumOffset_ = 3;
- static const int kCodeOffset_ = 4;
- static const int kCodeScopeInfoOffset_ = 5;
- static const int kFunctionScopeInfoOffset_ = 6;
- static const int kParentIndexOffset_ = 7;
- static const int kSharedFunctionInfoOffset_ = 8;
- static const int kLiteralNumOffset_ = 9;
- static const int kSize_ = 10;
-
- friend class JSArrayBasedStruct<FunctionInfoWrapper>;
-};
+ return result;
+}
-// Wraps SharedFunctionInfo along with some of its fields for passing it
-// back to JavaScript. SharedFunctionInfo object itself is additionally
-// wrapped into BlindReference for sanitizing reasons.
-class SharedInfoWrapper : public JSArrayBasedStruct<SharedInfoWrapper> {
- public:
- static bool IsInstance(Handle<JSArray> array) {
- return array->length() == Smi::FromInt(kSize_) &&
- Object::GetElementNoExceptionThrown(
- array->GetIsolate(), array, kSharedInfoOffset_)->IsJSValue();
- }
+Handle<Object> FunctionInfoWrapper::GetCodeScopeInfo() {
+ Handle<Object> element = this->GetField(kCodeScopeInfoOffset_);
+ return UnwrapJSValue(Handle<JSValue>::cast(element));
+}
- explicit SharedInfoWrapper(Handle<JSArray> array)
- : JSArrayBasedStruct<SharedInfoWrapper>(array) {
- }
- void SetProperties(Handle<String> name, int start_position, int end_position,
- Handle<SharedFunctionInfo> info) {
- HandleScope scope(isolate());
- this->SetField(kFunctionNameOffset_, name);
- Handle<JSValue> info_holder = WrapInJSValue(info);
- this->SetField(kSharedInfoOffset_, info_holder);
- this->SetSmiValueField(kStartPositionOffset_, start_position);
- this->SetSmiValueField(kEndPositionOffset_, end_position);
- }
- Handle<SharedFunctionInfo> GetInfo() {
- Handle<Object> element = this->GetField(kSharedInfoOffset_);
- Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
- return UnwrapSharedFunctionInfoFromJSValue(value_wrapper);
- }
+void SharedInfoWrapper::SetProperties(Handle<String> name,
+ int start_position,
+ int end_position,
+ Handle<SharedFunctionInfo> info) {
+ HandleScope scope(isolate());
+ this->SetField(kFunctionNameOffset_, name);
+ Handle<JSValue> info_holder = WrapInJSValue(info);
+ this->SetField(kSharedInfoOffset_, info_holder);
+ this->SetSmiValueField(kStartPositionOffset_, start_position);
+ this->SetSmiValueField(kEndPositionOffset_, end_position);
+}
- private:
- static const int kFunctionNameOffset_ = 0;
- static const int kStartPositionOffset_ = 1;
- static const int kEndPositionOffset_ = 2;
- static const int kSharedInfoOffset_ = 3;
- static const int kSize_ = 4;
- friend class JSArrayBasedStruct<SharedInfoWrapper>;
-};
+Handle<SharedFunctionInfo> SharedInfoWrapper::GetInfo() {
+ Handle<Object> element = this->GetField(kSharedInfoOffset_);
+ Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
+ return UnwrapSharedFunctionInfoFromJSValue(value_wrapper);
+}
class FunctionInfoListener {
@@ -813,6 +709,7 @@ class FunctionInfoListener {
info.SetInitialProperties(fun->name(), fun->start_position(),
fun->end_position(), fun->parameter_count(),
fun->materialized_literal_count(),
+ fun->slot_count(),
current_parent_index_);
current_parent_index_ = len_;
SetElementSloppy(result_, len_, info.GetJSArray());
@@ -823,8 +720,8 @@ class FunctionInfoListener {
HandleScope scope(isolate());
FunctionInfoWrapper info =
FunctionInfoWrapper::cast(
- *Object::GetElementNoExceptionThrown(
- isolate(), result_, current_parent_index_));
+ *Object::GetElement(
+ isolate(), result_, current_parent_index_).ToHandleChecked());
current_parent_index_ = info.GetParentIndex();
}
@@ -833,8 +730,8 @@ class FunctionInfoListener {
void FunctionCode(Handle<Code> function_code) {
FunctionInfoWrapper info =
FunctionInfoWrapper::cast(
- *Object::GetElementNoExceptionThrown(
- isolate(), result_, current_parent_index_));
+ *Object::GetElement(
+ isolate(), result_, current_parent_index_).ToHandleChecked());
info.SetFunctionCode(function_code,
Handle<HeapObject>(isolate()->heap()->null_value()));
}
@@ -848,14 +745,13 @@ class FunctionInfoListener {
}
FunctionInfoWrapper info =
FunctionInfoWrapper::cast(
- *Object::GetElementNoExceptionThrown(
- isolate(), result_, current_parent_index_));
+ *Object::GetElement(
+ isolate(), result_, current_parent_index_).ToHandleChecked());
info.SetFunctionCode(Handle<Code>(shared->code()),
Handle<HeapObject>(shared->scope_info()));
info.SetSharedFunctionInfo(shared);
- Handle<Object> scope_info_list(SerializeFunctionScope(scope, zone),
- isolate());
+ Handle<Object> scope_info_list = SerializeFunctionScope(scope, zone);
info.SetFunctionScopeInfo(scope_info_list);
}
@@ -864,9 +760,7 @@ class FunctionInfoListener {
private:
Isolate* isolate() const { return result_->GetIsolate(); }
- Object* SerializeFunctionScope(Scope* scope, Zone* zone) {
- HandleScope handle_scope(isolate());
-
+ Handle<Object> SerializeFunctionScope(Scope* scope, Zone* zone) {
Handle<JSArray> scope_info_list = isolate()->factory()->NewJSArray(10);
int scope_info_length = 0;
@@ -875,6 +769,7 @@ class FunctionInfoListener {
// scopes of this chain.
Scope* current_scope = scope;
while (current_scope != NULL) {
+ HandleScope handle_scope(isolate());
ZoneList<Variable*> stack_list(current_scope->StackLocalCount(), zone);
ZoneList<Variable*> context_list(
current_scope->ContextLocalCount(), zone);
@@ -901,7 +796,7 @@ class FunctionInfoListener {
current_scope = current_scope->outer_scope();
}
- return *scope_info_list;
+ return scope_info_list;
}
Handle<JSArray> result_;
@@ -910,8 +805,8 @@ class FunctionInfoListener {
};
-JSArray* LiveEdit::GatherCompileInfo(Handle<Script> script,
- Handle<String> source) {
+MaybeHandle<JSArray> LiveEdit::GatherCompileInfo(Handle<Script> script,
+ Handle<String> source) {
Isolate* isolate = script->GetIsolate();
FunctionInfoListener listener(isolate);
@@ -933,8 +828,7 @@ JSArray* LiveEdit::GatherCompileInfo(Handle<Script> script,
// A logical 'catch' section.
Handle<JSObject> rethrow_exception;
if (isolate->has_pending_exception()) {
- Handle<Object> exception(isolate->pending_exception()->ToObjectChecked(),
- isolate);
+ Handle<Object> exception(isolate->pending_exception(), isolate);
MessageLocation message_location = isolate->GetMessageLocation();
isolate->clear_pending_message();
@@ -954,13 +848,14 @@ JSArray* LiveEdit::GatherCompileInfo(Handle<Script> script,
Handle<Smi> start_pos(
Smi::FromInt(message_location.start_pos()), isolate);
Handle<Smi> end_pos(Smi::FromInt(message_location.end_pos()), isolate);
- Handle<JSValue> script_obj = GetScriptWrapper(message_location.script());
+ Handle<JSObject> script_obj =
+ Script::GetWrapper(message_location.script());
JSReceiver::SetProperty(
- rethrow_exception, start_pos_key, start_pos, NONE, SLOPPY);
+ rethrow_exception, start_pos_key, start_pos, NONE, SLOPPY).Assert();
JSReceiver::SetProperty(
- rethrow_exception, end_pos_key, end_pos, NONE, SLOPPY);
+ rethrow_exception, end_pos_key, end_pos, NONE, SLOPPY).Assert();
JSReceiver::SetProperty(
- rethrow_exception, script_obj_key, script_obj, NONE, SLOPPY);
+ rethrow_exception, script_obj_key, script_obj, NONE, SLOPPY).Assert();
}
}
@@ -969,10 +864,9 @@ JSArray* LiveEdit::GatherCompileInfo(Handle<Script> script,
script->set_source(*original_source);
if (rethrow_exception.is_null()) {
- return *(listener.GetResult());
+ return listener.GetResult();
} else {
- isolate->Throw(*rethrow_exception);
- return 0;
+ return isolate->Throw<JSArray>(rethrow_exception);
}
}
@@ -984,7 +878,7 @@ void LiveEdit::WrapSharedFunctionInfos(Handle<JSArray> array) {
for (int i = 0; i < len; i++) {
Handle<SharedFunctionInfo> info(
SharedFunctionInfo::cast(
- *Object::GetElementNoExceptionThrown(isolate, array, i)));
+ *Object::GetElement(isolate, array, i).ToHandleChecked()));
SharedInfoWrapper info_wrapper = SharedInfoWrapper::Create(isolate);
Handle<String> name_handle(String::cast(info->name()));
info_wrapper.SetProperties(name_handle, info->start_position(),
@@ -1261,15 +1155,10 @@ static void DeoptimizeDependentFunctions(SharedFunctionInfo* function_info) {
}
-MaybeObject* LiveEdit::ReplaceFunctionCode(
+void LiveEdit::ReplaceFunctionCode(
Handle<JSArray> new_compile_info_array,
Handle<JSArray> shared_info_array) {
Isolate* isolate = new_compile_info_array->GetIsolate();
- HandleScope scope(isolate);
-
- if (!SharedInfoWrapper::IsInstance(shared_info_array)) {
- return isolate->ThrowIllegalOperation();
- }
FunctionInfoWrapper compile_info_wrapper(new_compile_info_array);
SharedInfoWrapper shared_info_wrapper(shared_info_array);
@@ -1286,6 +1175,10 @@ MaybeObject* LiveEdit::ReplaceFunctionCode(
shared_info->set_scope_info(ScopeInfo::cast(*code_scope_info));
}
shared_info->DisableOptimization(kLiveEdit);
+ // Update the type feedback vector
+ Handle<FixedArray> feedback_vector =
+ compile_info_wrapper.GetFeedbackVector();
+ shared_info->set_feedback_vector(*feedback_vector);
}
if (shared_info->debug_info()->IsDebugInfo()) {
@@ -1307,27 +1200,15 @@ MaybeObject* LiveEdit::ReplaceFunctionCode(
DeoptimizeDependentFunctions(*shared_info);
isolate->compilation_cache()->Remove(shared_info);
-
- return isolate->heap()->undefined_value();
}
-MaybeObject* LiveEdit::FunctionSourceUpdated(
- Handle<JSArray> shared_info_array) {
- Isolate* isolate = shared_info_array->GetIsolate();
- HandleScope scope(isolate);
-
- if (!SharedInfoWrapper::IsInstance(shared_info_array)) {
- return isolate->ThrowIllegalOperation();
- }
-
+void LiveEdit::FunctionSourceUpdated(Handle<JSArray> shared_info_array) {
SharedInfoWrapper shared_info_wrapper(shared_info_array);
Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo();
DeoptimizeDependentFunctions(*shared_info);
- isolate->compilation_cache()->Remove(shared_info);
-
- return isolate->heap()->undefined_value();
+ shared_info_array->GetIsolate()->compilation_cache()->Remove(shared_info);
}
@@ -1359,21 +1240,21 @@ static int TranslatePosition(int original_position,
// TODO(635): binary search may be used here
for (int i = 0; i < array_len; i += 3) {
HandleScope scope(isolate);
- Handle<Object> element = Object::GetElementNoExceptionThrown(
- isolate, position_change_array, i);
+ Handle<Object> element = Object::GetElement(
+ isolate, position_change_array, i).ToHandleChecked();
CHECK(element->IsSmi());
int chunk_start = Handle<Smi>::cast(element)->value();
if (original_position < chunk_start) {
break;
}
- element = Object::GetElementNoExceptionThrown(
- isolate, position_change_array, i + 1);
+ element = Object::GetElement(
+ isolate, position_change_array, i + 1).ToHandleChecked();
CHECK(element->IsSmi());
int chunk_end = Handle<Smi>::cast(element)->value();
// Position mustn't be inside a chunk.
ASSERT(original_position >= chunk_end);
- element = Object::GetElementNoExceptionThrown(
- isolate, position_change_array, i + 2);
+ element = Object::GetElement(
+ isolate, position_change_array, i + 2).ToHandleChecked();
CHECK(element->IsSmi());
int chunk_changed_end = Handle<Smi>::cast(element)->value();
position_diff = chunk_changed_end - chunk_end;
@@ -1504,12 +1385,8 @@ static Handle<Code> PatchPositionsInCode(
}
-MaybeObject* LiveEdit::PatchFunctionPositions(
- Handle<JSArray> shared_info_array, Handle<JSArray> position_change_array) {
- if (!SharedInfoWrapper::IsInstance(shared_info_array)) {
- return shared_info_array->GetIsolate()->ThrowIllegalOperation();
- }
-
+void LiveEdit::PatchFunctionPositions(Handle<JSArray> shared_info_array,
+ Handle<JSArray> position_change_array) {
SharedInfoWrapper shared_info_wrapper(shared_info_array);
Handle<SharedFunctionInfo> info = shared_info_wrapper.GetInfo();
@@ -1540,8 +1417,6 @@ MaybeObject* LiveEdit::PatchFunctionPositions(
ReplaceCodeObject(Handle<Code>(info->code()), patched_code);
}
}
-
- return info->GetIsolate()->heap()->undefined_value();
}
@@ -1568,9 +1443,9 @@ static Handle<Script> CreateScriptCopy(Handle<Script> original) {
}
-Object* LiveEdit::ChangeScriptSource(Handle<Script> original_script,
- Handle<String> new_source,
- Handle<Object> old_script_name) {
+Handle<Object> LiveEdit::ChangeScriptSource(Handle<Script> original_script,
+ Handle<String> new_source,
+ Handle<Object> old_script_name) {
Isolate* isolate = original_script->GetIsolate();
Handle<Object> old_script_object;
if (old_script_name->IsString()) {
@@ -1588,7 +1463,7 @@ Object* LiveEdit::ChangeScriptSource(Handle<Script> original_script,
// Drop line ends so that they will be recalculated.
original_script->set_line_ends(isolate->heap()->undefined_value());
- return *old_script_object;
+ return old_script_object;
}
@@ -1630,7 +1505,7 @@ static bool CheckActivation(Handle<JSArray> shared_info_array,
for (int i = 0; i < len; i++) {
HandleScope scope(isolate);
Handle<Object> element =
- Object::GetElementNoExceptionThrown(isolate, shared_info_array, i);
+ Object::GetElement(isolate, shared_info_array, i).ToHandleChecked();
Handle<JSValue> jsvalue = Handle<JSValue>::cast(element);
Handle<SharedFunctionInfo> shared =
UnwrapSharedFunctionInfoFromJSValue(jsvalue);
@@ -1694,7 +1569,7 @@ static const char* DropFrames(Vector<StackFrame*> frames,
*mode = Debug::FRAME_DROPPED_IN_IC_CALL;
frame_has_padding = Debug::FramePaddingLayout::kIsSupported;
} else if (pre_top_frame_code ==
- isolate->debug()->debug_break_slot()) {
+ isolate->builtins()->builtin(Builtins::kSlot_DebugBreak)) {
// OK, we can drop debug break slot.
*mode = Debug::FRAME_DROPPED_IN_DEBUG_SLOT_CALL;
frame_has_padding = Debug::FramePaddingLayout::kIsSupported;
@@ -1947,7 +1822,7 @@ static const char* DropActivationsInActiveThread(
// Replace "blocked on active" with "replaced on active" status.
for (int i = 0; i < array_len; i++) {
Handle<Object> obj =
- Object::GetElementNoExceptionThrown(isolate, result, i);
+ Object::GetElement(isolate, result, i).ToHandleChecked();
if (*obj == Smi::FromInt(LiveEdit::FUNCTION_BLOCKED_ON_ACTIVE_STACK)) {
Handle<Object> replaced(
Smi::FromInt(LiveEdit::FUNCTION_REPLACED_ON_ACTIVE_STACK), isolate);
@@ -2013,8 +1888,8 @@ Handle<JSArray> LiveEdit::CheckAndDropActivations(
DropActivationsInActiveThread(shared_info_array, result, do_drop);
if (error_message != NULL) {
// Add error message as an array extra element.
- Handle<String> str = isolate->factory()->NewStringFromAscii(
- CStrVector(error_message));
+ Handle<String> str =
+ isolate->factory()->NewStringFromAsciiChecked(error_message);
SetElementSloppy(result, len, str);
}
return result;
@@ -2101,36 +1976,4 @@ bool LiveEditFunctionTracker::IsActive(Isolate* isolate) {
return isolate->active_function_info_listener() != NULL;
}
-
-#else // ENABLE_DEBUGGER_SUPPORT
-
-// This ifdef-else-endif section provides working or stub implementation of
-// LiveEditFunctionTracker.
-LiveEditFunctionTracker::LiveEditFunctionTracker(Isolate* isolate,
- FunctionLiteral* fun) {
-}
-
-
-LiveEditFunctionTracker::~LiveEditFunctionTracker() {
-}
-
-
-void LiveEditFunctionTracker::RecordFunctionInfo(
- Handle<SharedFunctionInfo> info, FunctionLiteral* lit,
- Zone* zone) {
-}
-
-
-void LiveEditFunctionTracker::RecordRootFunctionInfo(Handle<Code> code) {
-}
-
-
-bool LiveEditFunctionTracker::IsActive(Isolate* isolate) {
- return false;
-}
-
-#endif // ENABLE_DEBUGGER_SUPPORT
-
-
-
} } // namespace v8::internal
diff --git a/deps/v8/src/liveedit.h b/deps/v8/src/liveedit.h
index 0efbb95cc0..5be63ac0a1 100644
--- a/deps/v8/src/liveedit.h
+++ b/deps/v8/src/liveedit.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_LIVEEDIT_H_
#define V8_LIVEEDIT_H_
@@ -75,39 +52,36 @@ class LiveEditFunctionTracker {
static bool IsActive(Isolate* isolate);
private:
-#ifdef ENABLE_DEBUGGER_SUPPORT
Isolate* isolate_;
-#endif
};
-#ifdef ENABLE_DEBUGGER_SUPPORT
class LiveEdit : AllStatic {
public:
- static JSArray* GatherCompileInfo(Handle<Script> script,
- Handle<String> source);
+ MUST_USE_RESULT static MaybeHandle<JSArray> GatherCompileInfo(
+ Handle<Script> script,
+ Handle<String> source);
static void WrapSharedFunctionInfos(Handle<JSArray> array);
- MUST_USE_RESULT static MaybeObject* ReplaceFunctionCode(
- Handle<JSArray> new_compile_info_array,
- Handle<JSArray> shared_info_array);
+ static void ReplaceFunctionCode(Handle<JSArray> new_compile_info_array,
+ Handle<JSArray> shared_info_array);
- static MaybeObject* FunctionSourceUpdated(Handle<JSArray> shared_info_array);
+ static void FunctionSourceUpdated(Handle<JSArray> shared_info_array);
// Updates script field in FunctionSharedInfo.
static void SetFunctionScript(Handle<JSValue> function_wrapper,
Handle<Object> script_handle);
- MUST_USE_RESULT static MaybeObject* PatchFunctionPositions(
- Handle<JSArray> shared_info_array, Handle<JSArray> position_change_array);
+ static void PatchFunctionPositions(Handle<JSArray> shared_info_array,
+ Handle<JSArray> position_change_array);
// For a script updates its source field. If old_script_name is provided
// (i.e. is a String), also creates a copy of the script with its original
// source and sends notification to debugger.
- static Object* ChangeScriptSource(Handle<Script> original_script,
- Handle<String> new_source,
- Handle<Object> old_script_name);
+ static Handle<Object> ChangeScriptSource(Handle<Script> original_script,
+ Handle<String> new_source,
+ Handle<Object> old_script_name);
// In a code of a parent function replaces original function as embedded
// object with a substitution one.
@@ -175,9 +149,161 @@ class Comparator {
Output* result_writer);
};
-#endif // ENABLE_DEBUGGER_SUPPORT
+// Simple helper class that creates more or less typed structures over
+// JSArray object. This is an adhoc method of passing structures from C++
+// to JavaScript.
+template<typename S>
+class JSArrayBasedStruct {
+ public:
+ static S Create(Isolate* isolate) {
+ Factory* factory = isolate->factory();
+ Handle<JSArray> array = factory->NewJSArray(S::kSize_);
+ return S(array);
+ }
+
+ static S cast(Object* object) {
+ JSArray* array = JSArray::cast(object);
+ Handle<JSArray> array_handle(array);
+ return S(array_handle);
+ }
+
+ explicit JSArrayBasedStruct(Handle<JSArray> array) : array_(array) {
+ }
+
+ Handle<JSArray> GetJSArray() {
+ return array_;
+ }
+
+ Isolate* isolate() const {
+ return array_->GetIsolate();
+ }
+
+ protected:
+ void SetField(int field_position, Handle<Object> value) {
+ JSObject::SetElement(array_, field_position, value, NONE, SLOPPY).Assert();
+ }
+
+ void SetSmiValueField(int field_position, int value) {
+ SetField(field_position, Handle<Smi>(Smi::FromInt(value), isolate()));
+ }
+
+ Handle<Object> GetField(int field_position) {
+ return Object::GetElement(
+ isolate(), array_, field_position).ToHandleChecked();
+ }
+
+ int GetSmiValueField(int field_position) {
+ Handle<Object> res = GetField(field_position);
+ return Handle<Smi>::cast(res)->value();
+ }
+
+ private:
+ Handle<JSArray> array_;
+};
+
+
+// Represents some function compilation details. This structure will be used
+// from JavaScript. It contains Code object, which is kept wrapped
+// into a BlindReference for sanitizing reasons.
+class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> {
+ public:
+ explicit FunctionInfoWrapper(Handle<JSArray> array)
+ : JSArrayBasedStruct<FunctionInfoWrapper>(array) {
+ }
+
+ void SetInitialProperties(Handle<String> name,
+ int start_position,
+ int end_position,
+ int param_num,
+ int literal_count,
+ int slot_count,
+ int parent_index);
+
+ void SetFunctionCode(Handle<Code> function_code,
+ Handle<HeapObject> code_scope_info);
+
+ void SetFunctionScopeInfo(Handle<Object> scope_info_array) {
+ this->SetField(kFunctionScopeInfoOffset_, scope_info_array);
+ }
+
+ void SetSharedFunctionInfo(Handle<SharedFunctionInfo> info);
+
+ int GetLiteralCount() {
+ return this->GetSmiValueField(kLiteralNumOffset_);
+ }
+
+ int GetParentIndex() {
+ return this->GetSmiValueField(kParentIndexOffset_);
+ }
+
+ Handle<Code> GetFunctionCode();
+
+ Handle<FixedArray> GetFeedbackVector();
+
+ Handle<Object> GetCodeScopeInfo();
+
+ int GetStartPosition() {
+ return this->GetSmiValueField(kStartPositionOffset_);
+ }
+
+ int GetEndPosition() { return this->GetSmiValueField(kEndPositionOffset_); }
+
+ int GetSlotCount() {
+ return this->GetSmiValueField(kSlotNumOffset_);
+ }
+
+ private:
+ static const int kFunctionNameOffset_ = 0;
+ static const int kStartPositionOffset_ = 1;
+ static const int kEndPositionOffset_ = 2;
+ static const int kParamNumOffset_ = 3;
+ static const int kCodeOffset_ = 4;
+ static const int kCodeScopeInfoOffset_ = 5;
+ static const int kFunctionScopeInfoOffset_ = 6;
+ static const int kParentIndexOffset_ = 7;
+ static const int kSharedFunctionInfoOffset_ = 8;
+ static const int kLiteralNumOffset_ = 9;
+ static const int kSlotNumOffset_ = 10;
+ static const int kSize_ = 11;
+
+ friend class JSArrayBasedStruct<FunctionInfoWrapper>;
+};
+
+
+// Wraps SharedFunctionInfo along with some of its fields for passing it
+// back to JavaScript. SharedFunctionInfo object itself is additionally
+// wrapped into BlindReference for sanitizing reasons.
+class SharedInfoWrapper : public JSArrayBasedStruct<SharedInfoWrapper> {
+ public:
+ static bool IsInstance(Handle<JSArray> array) {
+ return array->length() == Smi::FromInt(kSize_) &&
+ Object::GetElement(array->GetIsolate(), array, kSharedInfoOffset_)
+ .ToHandleChecked()->IsJSValue();
+ }
+
+ explicit SharedInfoWrapper(Handle<JSArray> array)
+ : JSArrayBasedStruct<SharedInfoWrapper>(array) {
+ }
+
+ void SetProperties(Handle<String> name,
+ int start_position,
+ int end_position,
+ Handle<SharedFunctionInfo> info);
+
+ Handle<SharedFunctionInfo> GetInfo();
+
+ private:
+ static const int kFunctionNameOffset_ = 0;
+ static const int kStartPositionOffset_ = 1;
+ static const int kEndPositionOffset_ = 2;
+ static const int kSharedInfoOffset_ = 3;
+ static const int kSize_ = 4;
+
+ friend class JSArrayBasedStruct<SharedInfoWrapper>;
+};
+
} } // namespace v8::internal
#endif /* V*_LIVEEDIT_H_ */
diff --git a/deps/v8/src/log-inl.h b/deps/v8/src/log-inl.h
index 7f653cb728..d6781678c7 100644
--- a/deps/v8/src/log-inl.h
+++ b/deps/v8/src/log-inl.h
@@ -1,29 +1,6 @@
// Copyright 2006-2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_LOG_INL_H_
#define V8_LOG_INL_H_
diff --git a/deps/v8/src/log-utils.cc b/deps/v8/src/log-utils.cc
index 909d4a5139..687578847d 100644
--- a/deps/v8/src/log-utils.cc
+++ b/deps/v8/src/log-utils.cc
@@ -1,29 +1,6 @@
// Copyright 2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -51,7 +28,6 @@ void Log::Initialize(const char* log_file_name) {
// --log-all enables all the log flags.
if (FLAG_log_all) {
- FLAG_log_runtime = true;
FLAG_log_api = true;
FLAG_log_code = true;
FLAG_log_gc = true;
diff --git a/deps/v8/src/log-utils.h b/deps/v8/src/log-utils.h
index f1a21e2cc1..deb3f7c483 100644
--- a/deps/v8/src/log-utils.h
+++ b/deps/v8/src/log-utils.h
@@ -1,29 +1,6 @@
// Copyright 2006-2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_LOG_UTILS_H_
#define V8_LOG_UTILS_H_
@@ -45,10 +22,10 @@ class Log {
void stop() { is_stopped_ = true; }
static bool InitLogAtStart() {
- return FLAG_log || FLAG_log_runtime || FLAG_log_api
- || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect
- || FLAG_log_regexp || FLAG_ll_prof || FLAG_perf_basic_prof
- || FLAG_perf_jit_prof || FLAG_log_internal_timer_events;
+ return FLAG_log || FLAG_log_api || FLAG_log_code || FLAG_log_gc
+ || FLAG_log_handles || FLAG_log_suspect || FLAG_log_regexp
+ || FLAG_ll_prof || FLAG_perf_basic_prof || FLAG_perf_jit_prof
+ || FLAG_log_internal_timer_events;
}
// Frees all resources acquired in Initialize and Open... functions.
diff --git a/deps/v8/src/log.cc b/deps/v8/src/log.cc
index 942170c283..88dae56b7b 100644
--- a/deps/v8/src/log.cc
+++ b/deps/v8/src/log.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <stdarg.h>
@@ -1150,7 +1127,8 @@ void Logger::LogRegExpSource(Handle<JSRegExp> regexp) {
// (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"")
Log::MessageBuilder msg(log_);
- Handle<Object> source = GetProperty(regexp, "source");
+ Handle<Object> source = Object::GetProperty(
+ isolate_, regexp, "source").ToHandleChecked();
if (!source->IsString()) {
msg.Append("no source");
return;
@@ -1168,17 +1146,20 @@ void Logger::LogRegExpSource(Handle<JSRegExp> regexp) {
msg.Append('/');
// global flag
- Handle<Object> global = GetProperty(regexp, "global");
+ Handle<Object> global = Object::GetProperty(
+ isolate_, regexp, "global").ToHandleChecked();
if (global->IsTrue()) {
msg.Append('g');
}
// ignorecase flag
- Handle<Object> ignorecase = GetProperty(regexp, "ignoreCase");
+ Handle<Object> ignorecase = Object::GetProperty(
+ isolate_, regexp, "ignoreCase").ToHandleChecked();
if (ignorecase->IsTrue()) {
msg.Append('i');
}
// multiline flag
- Handle<Object> multiline = GetProperty(regexp, "multiline");
+ Handle<Object> multiline = Object::GetProperty(
+ isolate_, regexp, "multiline").ToHandleChecked();
if (multiline->IsTrue()) {
msg.Append('m');
}
@@ -1197,47 +1178,6 @@ void Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) {
}
-void Logger::LogRuntime(Vector<const char> format,
- Handle<JSArray> args) {
- if (!log_->IsEnabled() || !FLAG_log_runtime) return;
- Log::MessageBuilder msg(log_);
- for (int i = 0; i < format.length(); i++) {
- char c = format[i];
- if (c == '%' && i <= format.length() - 2) {
- i++;
- ASSERT('0' <= format[i] && format[i] <= '9');
- // No exception expected when getting an element from an array literal.
- Handle<Object> obj =
- Object::GetElementNoExceptionThrown(isolate_, args, format[i] - '0');
- i++;
- switch (format[i]) {
- case 's':
- msg.AppendDetailed(String::cast(*obj), false);
- break;
- case 'S':
- msg.AppendDetailed(String::cast(*obj), true);
- break;
- case 'r':
- Logger::LogRegExpSource(Handle<JSRegExp>::cast(obj));
- break;
- case 'x':
- msg.Append("0x%x", Smi::cast(*obj)->value());
- break;
- case 'i':
- msg.Append("%i", Smi::cast(*obj)->value());
- break;
- default:
- UNREACHABLE();
- }
- } else {
- msg.Append(c);
- }
- }
- msg.Append('\n');
- msg.WriteToLogFile();
-}
-
-
void Logger::ApiIndexedSecurityCheck(uint32_t index) {
if (!log_->IsEnabled() || !FLAG_log_api) return;
ApiEvent("api,check-security,%u\n", index);
@@ -1872,6 +1812,10 @@ void Logger::LogCodeObject(Object* object) {
description = "A load IC from the snapshot";
tag = Logger::LOAD_IC_TAG;
break;
+ case Code::CALL_IC:
+ description = "A call IC from the snapshot";
+ tag = Logger::CALL_IC_TAG;
+ break;
case Code::STORE_IC:
description = "A store IC from the snapshot";
tag = Logger::STORE_IC_TAG;
@@ -1904,9 +1848,9 @@ void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared,
Handle<String> func_name(shared->DebugName());
if (shared->script()->IsScript()) {
Handle<Script> script(Script::cast(shared->script()));
- int line_num = GetScriptLineNumber(script, shared->start_position()) + 1;
+ int line_num = Script::GetLineNumber(script, shared->start_position()) + 1;
int column_num =
- GetScriptColumnNumber(script, shared->start_position()) + 1;
+ Script::GetColumnNumber(script, shared->start_position()) + 1;
if (script->name()->IsString()) {
Handle<String> script_name(String::cast(script->name()));
if (line_num > 0) {
diff --git a/deps/v8/src/log.h b/deps/v8/src/log.h
index c01aca273a..b1a41e949f 100644
--- a/deps/v8/src/log.h
+++ b/deps/v8/src/log.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_LOG_H_
#define V8_LOG_H_
@@ -144,6 +121,7 @@ struct TickSample;
V(KEYED_STORE_POLYMORPHIC_IC_TAG, "KeyedStorePolymorphicIC") \
V(KEYED_EXTERNAL_ARRAY_STORE_IC_TAG, "KeyedExternalArrayStoreIC") \
V(LAZY_COMPILE_TAG, "LazyCompile") \
+ V(CALL_IC_TAG, "CallIC") \
V(LOAD_IC_TAG, "LoadIC") \
V(LOAD_POLYMORPHIC_IC_TAG, "LoadPolymorphicIC") \
V(REG_EXP_TAG, "RegExp") \
@@ -348,9 +326,6 @@ class Logger {
void RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache);
- // Log an event reported from generated code
- void LogRuntime(Vector<const char> format, Handle<JSArray> args);
-
bool is_logging() {
return is_logging_;
}
diff --git a/deps/v8/src/macro-assembler.h b/deps/v8/src/macro-assembler.h
index b05868c01b..bd22b93c72 100644
--- a/deps/v8/src/macro-assembler.h
+++ b/deps/v8/src/macro-assembler.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_MACRO_ASSEMBLER_H_
#define V8_MACRO_ASSEMBLER_H_
diff --git a/deps/v8/src/macros.py b/deps/v8/src/macros.py
index 0b69e6b80e..3eb906f74d 100644
--- a/deps/v8/src/macros.py
+++ b/deps/v8/src/macros.py
@@ -87,6 +87,10 @@ const kMaxYear = 1000000;
const kMinMonth = -10000000;
const kMaxMonth = 10000000;
+# Strict mode flags for passing to %SetProperty
+const kSloppyMode = 0;
+const kStrictMode = 1;
+
# Native cache ids.
const STRING_TO_REGEXP_CACHE_ID = 0;
@@ -97,7 +101,7 @@ const STRING_TO_REGEXP_CACHE_ID = 0;
# values of 'bar'.
macro IS_NULL(arg) = (arg === null);
macro IS_NULL_OR_UNDEFINED(arg) = (arg == null);
-macro IS_UNDEFINED(arg) = (typeof(arg) === 'undefined');
+macro IS_UNDEFINED(arg) = (arg === (void 0));
macro IS_NUMBER(arg) = (typeof(arg) === 'number');
macro IS_STRING(arg) = (typeof(arg) === 'string');
macro IS_BOOLEAN(arg) = (typeof(arg) === 'boolean');
@@ -272,3 +276,8 @@ const PROPERTY_ATTRIBUTES_NONE = 0;
const PROPERTY_ATTRIBUTES_STRING = 8;
const PROPERTY_ATTRIBUTES_SYMBOLIC = 16;
const PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL = 32;
+
+# Use for keys, values and entries iterators.
+const ITERATOR_KIND_KEYS = 1;
+const ITERATOR_KIND_VALUES = 2;
+const ITERATOR_KIND_ENTRIES = 3;
diff --git a/deps/v8/src/mark-compact-inl.h b/deps/v8/src/mark-compact-inl.h
index a42e0f7f12..608a0ec98e 100644
--- a/deps/v8/src/mark-compact-inl.h
+++ b/deps/v8/src/mark-compact-inl.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_MARK_COMPACT_INL_H_
#define V8_MARK_COMPACT_INL_H_
diff --git a/deps/v8/src/mark-compact.cc b/deps/v8/src/mark-compact.cc
index f04a8bcb9a..ec8e941795 100644
--- a/deps/v8/src/mark-compact.cc
+++ b/deps/v8/src/mark-compact.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -40,6 +17,7 @@
#include "mark-compact.h"
#include "objects-visiting.h"
#include "objects-visiting-inl.h"
+#include "spaces-inl.h"
#include "stub-cache.h"
#include "sweeper-thread.h"
@@ -449,7 +427,7 @@ void MarkCompactCollector::CollectGarbage() {
#ifdef VERIFY_HEAP
if (heap()->weak_embedded_objects_verification_enabled()) {
- VerifyWeakEmbeddedObjectsInOptimizedCode();
+ VerifyWeakEmbeddedObjectsInCode();
}
if (FLAG_collect_maps && FLAG_omit_map_checks_for_leaf_maps) {
VerifyOmittedMapChecks();
@@ -510,13 +488,13 @@ void MarkCompactCollector::VerifyMarkbitsAreClean() {
}
-void MarkCompactCollector::VerifyWeakEmbeddedObjectsInOptimizedCode() {
+void MarkCompactCollector::VerifyWeakEmbeddedObjectsInCode() {
HeapObjectIterator code_iterator(heap()->code_space());
for (HeapObject* obj = code_iterator.Next();
obj != NULL;
obj = code_iterator.Next()) {
Code* code = Code::cast(obj);
- if (code->kind() != Code::OPTIMIZED_FUNCTION) continue;
+ if (!code->is_optimized_code() && !code->is_weak_stub()) continue;
if (WillBeDeoptimized(code)) continue;
code->VerifyEmbeddedObjectsDependency();
}
@@ -595,11 +573,8 @@ class MarkCompactCollector::SweeperTask : public v8::Task {
void MarkCompactCollector::StartSweeperThreads() {
- // TODO(hpayer): This check is just used for debugging purpose and
- // should be removed or turned into an assert after investigating the
- // crash in concurrent sweeping.
- CHECK(free_list_old_pointer_space_.get()->IsEmpty());
- CHECK(free_list_old_data_space_.get()->IsEmpty());
+ ASSERT(free_list_old_pointer_space_.get()->IsEmpty());
+ ASSERT(free_list_old_data_space_.get()->IsEmpty());
sweeping_pending_ = true;
for (int i = 0; i < isolate()->num_sweeper_threads(); i++) {
isolate()->sweeper_threads()[i]->StartSweeping();
@@ -627,14 +602,30 @@ void MarkCompactCollector::WaitUntilSweepingCompleted() {
}
ParallelSweepSpacesComplete();
sweeping_pending_ = false;
- RefillFreeLists(heap()->paged_space(OLD_DATA_SPACE));
- RefillFreeLists(heap()->paged_space(OLD_POINTER_SPACE));
+ RefillFreeList(heap()->paged_space(OLD_DATA_SPACE));
+ RefillFreeList(heap()->paged_space(OLD_POINTER_SPACE));
heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes();
heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes();
}
-intptr_t MarkCompactCollector::RefillFreeLists(PagedSpace* space) {
+bool MarkCompactCollector::IsSweepingCompleted() {
+ for (int i = 0; i < isolate()->num_sweeper_threads(); i++) {
+ if (!isolate()->sweeper_threads()[i]->SweepingCompleted()) {
+ return false;
+ }
+ }
+ if (FLAG_job_based_sweeping) {
+ if (!pending_sweeper_jobs_semaphore_.WaitFor(TimeDelta::FromSeconds(0))) {
+ return false;
+ }
+ pending_sweeper_jobs_semaphore_.Signal();
+ }
+ return true;
+}
+
+
+void MarkCompactCollector::RefillFreeList(PagedSpace* space) {
FreeList* free_list;
if (space == heap()->old_pointer_space()) {
@@ -644,13 +635,12 @@ intptr_t MarkCompactCollector::RefillFreeLists(PagedSpace* space) {
} else {
// Any PagedSpace might invoke RefillFreeLists, so we need to make sure
// to only refill them for old data and pointer spaces.
- return 0;
+ return;
}
intptr_t freed_bytes = space->free_list()->Concatenate(free_list);
space->AddToAccountingStats(freed_bytes);
space->DecrementUnsweptFreeBytes(freed_bytes);
- return freed_bytes;
}
@@ -2070,8 +2060,8 @@ int MarkCompactCollector::DiscoverAndPromoteBlackObjectsOnPage(
}
// Promotion failed. Just migrate object to another semispace.
- MaybeObject* allocation = new_space->AllocateRaw(size);
- if (allocation->IsFailure()) {
+ AllocationResult allocation = new_space->AllocateRaw(size);
+ if (allocation.IsRetry()) {
if (!new_space->AddFreshPage()) {
// Shouldn't happen. We are sweeping linearly, and to-space
// has the same number of pages as from-space, so there is
@@ -2079,9 +2069,9 @@ int MarkCompactCollector::DiscoverAndPromoteBlackObjectsOnPage(
UNREACHABLE();
}
allocation = new_space->AllocateRaw(size);
- ASSERT(!allocation->IsFailure());
+ ASSERT(!allocation.IsRetry());
}
- Object* target = allocation->ToObjectUnchecked();
+ Object* target = allocation.ToObjectChecked();
MigrateObject(HeapObject::cast(target),
object,
@@ -2146,7 +2136,10 @@ void MarkCompactCollector::MarkStringTable(RootMarkingVisitor* visitor) {
StringTable* string_table = heap()->string_table();
// Mark the string table itself.
MarkBit string_table_mark = Marking::MarkBitFrom(string_table);
- SetMark(string_table, string_table_mark);
+ if (!string_table_mark.Get()) {
+ // String table could have already been marked by visiting the handles list.
+ SetMark(string_table, string_table_mark);
+ }
// Explicitly mark the prefix.
string_table->IteratePrefix(visitor);
ProcessMarkingDeque();
@@ -2583,7 +2576,7 @@ void MarkCompactCollector::ClearNonLiveReferences() {
if (map_mark.Get()) {
ClearNonLiveDependentCode(map->dependent_code());
} else {
- ClearAndDeoptimizeDependentCode(map->dependent_code());
+ ClearDependentCode(map->dependent_code());
map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array()));
}
}
@@ -2638,7 +2631,7 @@ void MarkCompactCollector::ClearNonLiveReferences() {
}
ClearNonLiveDependentCode(DependentCode::cast(value));
} else {
- ClearAndDeoptimizeDependentCode(DependentCode::cast(value));
+ ClearDependentCode(DependentCode::cast(value));
table->set(key_index, heap_->the_hole_value());
table->set(value_index, heap_->the_hole_value());
}
@@ -2708,56 +2701,102 @@ void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map,
}
-void MarkCompactCollector::ClearAndDeoptimizeDependentCode(
+void MarkCompactCollector::ClearDependentICList(Object* head) {
+ Object* current = head;
+ Object* undefined = heap()->undefined_value();
+ while (current != undefined) {
+ Code* code = Code::cast(current);
+ if (IsMarked(code)) {
+ ASSERT(code->is_weak_stub());
+ IC::InvalidateMaps(code);
+ }
+ current = code->next_code_link();
+ code->set_next_code_link(undefined);
+ }
+}
+
+
+void MarkCompactCollector::ClearDependentCode(
DependentCode* entries) {
DisallowHeapAllocation no_allocation;
DependentCode::GroupStartIndexes starts(entries);
int number_of_entries = starts.number_of_entries();
if (number_of_entries == 0) return;
- for (int i = 0; i < number_of_entries; i++) {
+ int g = DependentCode::kWeakICGroup;
+ if (starts.at(g) != starts.at(g + 1)) {
+ int i = starts.at(g);
+ ASSERT(i + 1 == starts.at(g + 1));
+ Object* head = entries->object_at(i);
+ ClearDependentICList(head);
+ }
+ g = DependentCode::kWeakCodeGroup;
+ for (int i = starts.at(g); i < starts.at(g + 1); i++) {
// If the entry is compilation info then the map must be alive,
- // and ClearAndDeoptimizeDependentCode shouldn't be called.
+ // and ClearDependentCode shouldn't be called.
ASSERT(entries->is_code_at(i));
Code* code = entries->code_at(i);
-
if (IsMarked(code) && !code->marked_for_deoptimization()) {
code->set_marked_for_deoptimization(true);
code->InvalidateEmbeddedObjects();
have_code_to_deoptimize_ = true;
}
+ }
+ for (int i = 0; i < number_of_entries; i++) {
entries->clear_at(i);
}
}
-void MarkCompactCollector::ClearNonLiveDependentCode(DependentCode* entries) {
- DisallowHeapAllocation no_allocation;
- DependentCode::GroupStartIndexes starts(entries);
- int number_of_entries = starts.number_of_entries();
- if (number_of_entries == 0) return;
- int new_number_of_entries = 0;
- // Go through all groups, remove dead codes and compact.
- for (int g = 0; g < DependentCode::kGroupCount; g++) {
- int group_number_of_entries = 0;
- for (int i = starts.at(g); i < starts.at(g + 1); i++) {
+int MarkCompactCollector::ClearNonLiveDependentCodeInGroup(
+ DependentCode* entries, int group, int start, int end, int new_start) {
+ int survived = 0;
+ if (group == DependentCode::kWeakICGroup) {
+ // Dependent weak IC stubs form a linked list and only the head is stored
+ // in the dependent code array.
+ if (start != end) {
+ ASSERT(start + 1 == end);
+ Object* old_head = entries->object_at(start);
+ MarkCompactWeakObjectRetainer retainer;
+ Object* head = VisitWeakList<Code>(heap(), old_head, &retainer, true);
+ entries->set_object_at(new_start, head);
+ Object** slot = entries->slot_at(new_start);
+ RecordSlot(slot, slot, head);
+ // We do not compact this group even if the head is undefined,
+ // more dependent ICs are likely to be added later.
+ survived = 1;
+ }
+ } else {
+ for (int i = start; i < end; i++) {
Object* obj = entries->object_at(i);
ASSERT(obj->IsCode() || IsMarked(obj));
if (IsMarked(obj) &&
(!obj->IsCode() || !WillBeDeoptimized(Code::cast(obj)))) {
- if (new_number_of_entries + group_number_of_entries != i) {
- entries->set_object_at(
- new_number_of_entries + group_number_of_entries, obj);
+ if (new_start + survived != i) {
+ entries->set_object_at(new_start + survived, obj);
}
- Object** slot = entries->slot_at(new_number_of_entries +
- group_number_of_entries);
+ Object** slot = entries->slot_at(new_start + survived);
RecordSlot(slot, slot, obj);
- group_number_of_entries++;
+ survived++;
}
}
- entries->set_number_of_entries(
- static_cast<DependentCode::DependencyGroup>(g),
- group_number_of_entries);
- new_number_of_entries += group_number_of_entries;
+ }
+ entries->set_number_of_entries(
+ static_cast<DependentCode::DependencyGroup>(group), survived);
+ return survived;
+}
+
+
+void MarkCompactCollector::ClearNonLiveDependentCode(DependentCode* entries) {
+ DisallowHeapAllocation no_allocation;
+ DependentCode::GroupStartIndexes starts(entries);
+ int number_of_entries = starts.number_of_entries();
+ if (number_of_entries == 0) return;
+ int new_number_of_entries = 0;
+ // Go through all groups, remove dead codes and compact.
+ for (int g = 0; g < DependentCode::kGroupCount; g++) {
+ int survived = ClearNonLiveDependentCodeInGroup(
+ entries, g, starts.at(g), starts.at(g + 1), new_number_of_entries);
+ new_number_of_entries += survived;
}
for (int i = new_number_of_entries; i < number_of_entries; i++) {
entries->clear_at(i);
@@ -2988,25 +3027,30 @@ class PointersUpdatingVisitor: public ObjectVisitor {
};
-static void UpdatePointer(HeapObject** p, HeapObject* object) {
- ASSERT(*p == object);
-
- Address old_addr = object->address();
-
- Address new_addr = Memory::Address_at(old_addr);
+static void UpdatePointer(HeapObject** address, HeapObject* object) {
+ Address new_addr = Memory::Address_at(object->address());
// The new space sweep will overwrite the map word of dead objects
// with NULL. In this case we do not need to transfer this entry to
// the store buffer which we are rebuilding.
+ // We perform the pointer update with a no barrier compare-and-swap. The
+ // compare and swap may fail in the case where the pointer update tries to
+ // update garbage memory which was concurrently accessed by the sweeper.
if (new_addr != NULL) {
- *p = HeapObject::FromAddress(new_addr);
+ NoBarrier_CompareAndSwap(
+ reinterpret_cast<AtomicWord*>(address),
+ reinterpret_cast<AtomicWord>(object),
+ reinterpret_cast<AtomicWord>(HeapObject::FromAddress(new_addr)));
} else {
// We have to zap this pointer, because the store buffer may overflow later,
// and then we have to scan the entire heap and we don't want to find
// spurious newspace pointers in the old space.
// TODO(mstarzinger): This was changed to a sentinel value to track down
// rare crashes, change it back to Smi::FromInt(0) later.
- *p = reinterpret_cast<HeapObject*>(Smi::FromInt(0x0f100d00 >> 1)); // flood
+ NoBarrier_CompareAndSwap(
+ reinterpret_cast<AtomicWord*>(address),
+ reinterpret_cast<AtomicWord>(object),
+ reinterpret_cast<AtomicWord>(Smi::FromInt(0x0f100d00 >> 1)));
}
}
@@ -3025,17 +3069,15 @@ static String* UpdateReferenceInExternalStringTableEntry(Heap* heap,
bool MarkCompactCollector::TryPromoteObject(HeapObject* object,
int object_size) {
- // TODO(hpayer): Replace that check with an assert.
- CHECK(object_size <= Page::kMaxRegularHeapObjectSize);
+ ASSERT(object_size <= Page::kMaxRegularHeapObjectSize);
OldSpace* target_space = heap()->TargetSpace(object);
ASSERT(target_space == heap()->old_pointer_space() ||
target_space == heap()->old_data_space());
- Object* result;
- MaybeObject* maybe_result = target_space->AllocateRaw(object_size);
- if (maybe_result->ToObject(&result)) {
- HeapObject* target = HeapObject::cast(result);
+ HeapObject* target;
+ AllocationResult allocation = target_space->AllocateRaw(object_size);
+ if (allocation.To(&target)) {
MigrateObject(target,
object,
object_size,
@@ -3106,19 +3148,15 @@ void MarkCompactCollector::EvacuateLiveObjectsFromPage(Page* p) {
int size = object->Size();
- MaybeObject* target = space->AllocateRaw(size);
- if (target->IsFailure()) {
+ HeapObject* target_object;
+ AllocationResult allocation = space->AllocateRaw(size);
+ if (!allocation.To(&target_object)) {
// OS refused to give us memory.
V8::FatalProcessOutOfMemory("Evacuation");
return;
}
- Object* target_object = target->ToObjectUnchecked();
-
- MigrateObject(HeapObject::cast(target_object),
- object,
- size,
- space->identity());
+ MigrateObject(target_object, object, size, space->identity());
ASSERT(object->map_word().IsForwardingAddress());
}
@@ -3133,12 +3171,10 @@ void MarkCompactCollector::EvacuatePages() {
int npages = evacuation_candidates_.length();
for (int i = 0; i < npages; i++) {
Page* p = evacuation_candidates_[i];
- // TODO(hpayer): This check is just used for debugging purpose and
- // should be removed or turned into an assert after investigating the
- // crash in concurrent sweeping.
- CHECK(p->IsEvacuationCandidate() ||
- p->IsFlagSet(Page::RESCAN_ON_EVACUATION));
- CHECK_EQ(static_cast<int>(p->parallel_sweeping()), 0);
+ ASSERT(p->IsEvacuationCandidate() ||
+ p->IsFlagSet(Page::RESCAN_ON_EVACUATION));
+ ASSERT(static_cast<int>(p->parallel_sweeping()) ==
+ MemoryChunk::PARALLEL_SWEEPING_DONE);
if (p->IsEvacuationCandidate()) {
// During compaction we might have to request a new page.
// Check that space still have room for that.
@@ -3152,7 +3188,6 @@ void MarkCompactCollector::EvacuatePages() {
slots_buffer_allocator_.DeallocateChain(page->slots_buffer_address());
page->ClearEvacuationCandidate();
page->SetFlag(Page::RESCAN_ON_EVACUATION);
- page->InsertAfter(static_cast<PagedSpace*>(page->owner())->anchor());
}
return;
}
@@ -3409,7 +3444,7 @@ void MarkCompactCollector::InvalidateCode(Code* code) {
// Return true if the given code is deoptimized or will be deoptimized.
bool MarkCompactCollector::WillBeDeoptimized(Code* code) {
- return code->marked_for_deoptimization();
+ return code->is_optimized_code() && code->marked_for_deoptimization();
}
@@ -3616,7 +3651,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
WeakHashTable* table =
WeakHashTable::cast(heap_->weak_object_to_code_table());
table->Iterate(&updating_visitor);
- table->Rehash(heap_->undefined_value());
+ table->Rehash(heap_->isolate()->factory()->undefined_value());
}
// Update pointers from external string table.
@@ -3643,14 +3678,14 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
}
-void MarkCompactCollector::UnlinkEvacuationCandidates() {
+void MarkCompactCollector::MoveEvacuationCandidatesToEndOfPagesList() {
int npages = evacuation_candidates_.length();
for (int i = 0; i < npages; i++) {
Page* p = evacuation_candidates_[i];
if (!p->IsEvacuationCandidate()) continue;
p->Unlink();
- p->ClearSweptPrecisely();
- p->ClearSweptConservatively();
+ PagedSpace* space = static_cast<PagedSpace*>(p->owner());
+ p->InsertAfter(space->LastPage());
}
}
@@ -3665,7 +3700,7 @@ void MarkCompactCollector::ReleaseEvacuationCandidates() {
p->set_scan_on_scavenge(false);
slots_buffer_allocator_.DeallocateChain(p->slots_buffer_address());
p->ResetLiveBytes();
- space->ReleasePage(p, false);
+ space->ReleasePage(p);
}
evacuation_candidates_.Rewind(0);
compacting_ = false;
@@ -3987,10 +4022,7 @@ template<MarkCompactCollector::SweepingParallelism mode>
intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space,
FreeList* free_list,
Page* p) {
- // TODO(hpayer): This check is just used for debugging purpose and
- // should be removed or turned into an assert after investigating the
- // crash in concurrent sweeping.
- CHECK(!p->IsEvacuationCandidate() && !p->WasSwept());
+ ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL &&
free_list != NULL) ||
(mode == MarkCompactCollector::SWEEP_SEQUENTIALLY &&
@@ -4092,35 +4124,37 @@ void MarkCompactCollector::SweepInParallel(PagedSpace* space) {
free_list->Concatenate(&private_free_list);
p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_FINALIZE);
}
+ if (p == space->end_of_unswept_pages()) break;
}
}
void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
space->set_was_swept_conservatively(sweeper == CONSERVATIVE ||
- sweeper == LAZY_CONSERVATIVE ||
sweeper == PARALLEL_CONSERVATIVE ||
sweeper == CONCURRENT_CONSERVATIVE);
space->ClearStats();
+ // We defensively initialize end_of_unswept_pages_ here with the first page
+ // of the pages list.
+ space->set_end_of_unswept_pages(space->FirstPage());
+
PageIterator it(space);
int pages_swept = 0;
- bool lazy_sweeping_active = false;
bool unused_page_present = false;
bool parallel_sweeping_active = false;
while (it.has_next()) {
Page* p = it.next();
-
ASSERT(p->parallel_sweeping() == MemoryChunk::PARALLEL_SWEEPING_DONE);
- ASSERT(!p->IsEvacuationCandidate());
// Clear sweeping flags indicating that marking bits are still intact.
p->ClearSweptPrecisely();
p->ClearSweptConservatively();
- if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION)) {
+ if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION) ||
+ p->IsEvacuationCandidate()) {
// Will be processed in EvacuateNewSpaceAndCandidates.
ASSERT(evacuation_candidates_.length() > 0);
continue;
@@ -4136,7 +4170,7 @@ void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
// Adjust unswept free bytes because releasing a page expects said
// counter to be accurate for unswept pages.
space->IncreaseUnsweptFreeBytes(p);
- space->ReleasePage(p, true);
+ space->ReleasePage(p);
continue;
}
unused_page_present = true;
@@ -4152,25 +4186,6 @@ void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
pages_swept++;
break;
}
- case LAZY_CONSERVATIVE: {
- if (lazy_sweeping_active) {
- if (FLAG_gc_verbose) {
- PrintF("Sweeping 0x%" V8PRIxPTR " lazily postponed.\n",
- reinterpret_cast<intptr_t>(p));
- }
- space->IncreaseUnsweptFreeBytes(p);
- } else {
- if (FLAG_gc_verbose) {
- PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n",
- reinterpret_cast<intptr_t>(p));
- }
- SweepConservatively<SWEEP_SEQUENTIALLY>(space, NULL, p);
- pages_swept++;
- space->SetPagesToSweep(p->next_page());
- lazy_sweeping_active = true;
- }
- break;
- }
case CONCURRENT_CONSERVATIVE:
case PARALLEL_CONSERVATIVE: {
if (!parallel_sweeping_active) {
@@ -4189,6 +4204,7 @@ void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_PENDING);
space->IncreaseUnsweptFreeBytes(p);
}
+ space->set_end_of_unswept_pages(p);
break;
}
case PRECISE: {
@@ -4231,17 +4247,14 @@ void MarkCompactCollector::SweepSpaces() {
#ifdef DEBUG
state_ = SWEEP_SPACES;
#endif
- SweeperType how_to_sweep =
- FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE;
+ SweeperType how_to_sweep = CONSERVATIVE;
if (AreSweeperThreadsActivated()) {
if (FLAG_parallel_sweeping) how_to_sweep = PARALLEL_CONSERVATIVE;
if (FLAG_concurrent_sweeping) how_to_sweep = CONCURRENT_CONSERVATIVE;
}
if (sweep_precisely_) how_to_sweep = PRECISE;
- // Unlink evacuation candidates before sweeper threads access the list of
- // pages to avoid race condition.
- UnlinkEvacuationCandidates();
+ MoveEvacuationCandidatesToEndOfPagesList();
// Noncompacting collections simply sweep the spaces to clear the mark
// bits and free the nonlive blocks (for old and map spaces). We sweep
@@ -4256,7 +4269,6 @@ void MarkCompactCollector::SweepSpaces() {
if (how_to_sweep == PARALLEL_CONSERVATIVE ||
how_to_sweep == CONCURRENT_CONSERVATIVE) {
- // TODO(hpayer): fix race with concurrent sweeper
StartSweeperThreads();
}
@@ -4305,12 +4317,10 @@ void MarkCompactCollector::ParallelSweepSpacesComplete() {
void MarkCompactCollector::EnableCodeFlushing(bool enable) {
-#ifdef ENABLE_DEBUGGER_SUPPORT
if (isolate()->debug()->IsLoaded() ||
isolate()->debug()->has_break_points()) {
enable = false;
}
-#endif
if (enable) {
if (code_flusher_ != NULL) return;
diff --git a/deps/v8/src/mark-compact.h b/deps/v8/src/mark-compact.h
index 0ebe8a0f74..254f2589c9 100644
--- a/deps/v8/src/mark-compact.h
+++ b/deps/v8/src/mark-compact.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_MARK_COMPACT_H_
#define V8_MARK_COMPACT_H_
@@ -536,35 +513,6 @@ class ThreadLocalTop;
// Mark-Compact collector
class MarkCompactCollector {
public:
- // Type of functions to compute forwarding addresses of objects in
- // compacted spaces. Given an object and its size, return a (non-failure)
- // Object* that will be the object after forwarding. There is a separate
- // allocation function for each (compactable) space based on the location
- // of the object before compaction.
- typedef MaybeObject* (*AllocationFunction)(Heap* heap,
- HeapObject* object,
- int object_size);
-
- // Type of functions to encode the forwarding address for an object.
- // Given the object, its size, and the new (non-failure) object it will be
- // forwarded to, encode the forwarding address. For paged spaces, the
- // 'offset' input/output parameter contains the offset of the forwarded
- // object from the forwarding address of the previous live object in the
- // page as input, and is updated to contain the offset to be used for the
- // next live object in the same page. For spaces using a different
- // encoding (i.e., contiguous spaces), the offset parameter is ignored.
- typedef void (*EncodingFunction)(Heap* heap,
- HeapObject* old_object,
- int object_size,
- Object* new_object,
- int* offset);
-
- // Type of functions to process non-live objects.
- typedef void (*ProcessNonLiveFunction)(HeapObject* object, Isolate* isolate);
-
- // Pointer to member function, used in IterateLiveObjects.
- typedef int (MarkCompactCollector::*LiveObjectCallback)(HeapObject* obj);
-
// Set the global flags, it must be called before Prepare to take effect.
inline void SetFlags(int flags);
@@ -623,7 +571,6 @@ class MarkCompactCollector {
enum SweeperType {
CONSERVATIVE,
- LAZY_CONSERVATIVE,
PARALLEL_CONSERVATIVE,
CONCURRENT_CONSERVATIVE,
PRECISE
@@ -638,7 +585,7 @@ class MarkCompactCollector {
void VerifyMarkbitsAreClean();
static void VerifyMarkbitsAreClean(PagedSpace* space);
static void VerifyMarkbitsAreClean(NewSpace* space);
- void VerifyWeakEmbeddedObjectsInOptimizedCode();
+ void VerifyWeakEmbeddedObjectsInCode();
void VerifyOmittedMapChecks();
#endif
@@ -724,7 +671,9 @@ class MarkCompactCollector {
void WaitUntilSweepingCompleted();
- intptr_t RefillFreeLists(PagedSpace* space);
+ bool IsSweepingCompleted();
+
+ void RefillFreeList(PagedSpace* space);
bool AreSweeperThreadsActivated();
@@ -743,7 +692,7 @@ class MarkCompactCollector {
void MarkWeakObjectToCodeTable();
// Special case for processing weak references in a full collection. We need
- // to artifically keep AllocationSites alive for a time.
+ // to artificially keep AllocationSites alive for a time.
void MarkAllocationSite(AllocationSite* site);
private:
@@ -757,9 +706,6 @@ class MarkCompactCollector {
void RemoveDeadInvalidatedCode();
void ProcessInvalidatedCode(ObjectVisitor* visitor);
- void UnlinkEvacuationCandidates();
- void ReleaseEvacuationCandidates();
-
void StartSweeperThreads();
#ifdef DEBUG
@@ -899,8 +845,11 @@ class MarkCompactCollector {
void ClearNonLivePrototypeTransitions(Map* map);
void ClearNonLiveMapTransitions(Map* map, MarkBit map_mark);
- void ClearAndDeoptimizeDependentCode(DependentCode* dependent_code);
+ void ClearDependentCode(DependentCode* dependent_code);
+ void ClearDependentICList(Object* head);
void ClearNonLiveDependentCode(DependentCode* dependent_code);
+ int ClearNonLiveDependentCodeInGroup(DependentCode* dependent_code, int group,
+ int start, int end, int new_start);
// Marking detaches initial maps from SharedFunctionInfo objects
// to make this reference weak. We need to reattach initial maps
@@ -945,6 +894,12 @@ class MarkCompactCollector {
void EvacuateNewSpaceAndCandidates();
+ void ReleaseEvacuationCandidates();
+
+ // Moves the pages of the evacuation_candidates_ list to the end of their
+ // corresponding space pages list.
+ void MoveEvacuationCandidatesToEndOfPagesList();
+
void SweepSpace(PagedSpace* space, SweeperType sweeper);
// Finalizes the parallel sweeping phase. Marks all the pages that were
diff --git a/deps/v8/src/math.js b/deps/v8/src/math.js
index da96d967e1..f8738b5f85 100644
--- a/deps/v8/src/math.js
+++ b/deps/v8/src/math.js
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file relies on the fact that the following declarations have been made
// in runtime.js:
@@ -52,24 +29,24 @@ function MathAbs(x) {
// ECMA 262 - 15.8.2.2
function MathAcos(x) {
- return %Math_acos(TO_NUMBER_INLINE(x));
+ return %MathAcos(TO_NUMBER_INLINE(x));
}
// ECMA 262 - 15.8.2.3
function MathAsin(x) {
- return %Math_asin(TO_NUMBER_INLINE(x));
+ return %MathAsin(TO_NUMBER_INLINE(x));
}
// ECMA 262 - 15.8.2.4
function MathAtan(x) {
- return %Math_atan(TO_NUMBER_INLINE(x));
+ return %MathAtan(TO_NUMBER_INLINE(x));
}
// ECMA 262 - 15.8.2.5
// The naming of y and x matches the spec, as does the order in which
// ToNumber (valueOf) is called.
function MathAtan2(y, x) {
- return %Math_atan2(TO_NUMBER_INLINE(y), TO_NUMBER_INLINE(x));
+ return %MathAtan2(TO_NUMBER_INLINE(y), TO_NUMBER_INLINE(x));
}
// ECMA 262 - 15.8.2.6
@@ -85,7 +62,7 @@ function MathCos(x) {
// ECMA 262 - 15.8.2.8
function MathExp(x) {
- return %Math_exp(TO_NUMBER_INLINE(x));
+ return %MathExp(TO_NUMBER_INLINE(x));
}
// ECMA 262 - 15.8.2.9
@@ -100,7 +77,7 @@ function MathFloor(x) {
// has to be -0, which wouldn't be the case with the shift.
return TO_UINT32(x);
} else {
- return %Math_floor(x);
+ return %MathFloor(x);
}
}
diff --git a/deps/v8/src/messages.cc b/deps/v8/src/messages.cc
index 0077d0309f..8c084e266f 100644
--- a/deps/v8/src/messages.cc
+++ b/deps/v8/src/messages.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -78,7 +55,7 @@ Handle<JSMessageObject> MessageHandler::MakeMessageObject(
if (loc) {
start = loc->start_pos();
end = loc->end_pos();
- script_handle = GetScriptWrapper(loc->script());
+ script_handle = Script::GetWrapper(loc->script());
}
Handle<Object> stack_frames_handle = stack_frames.is_null()
@@ -107,7 +84,7 @@ void MessageHandler::ReportMessage(Isolate* isolate,
// We pass the exception object into the message handler callback though.
Object* exception_object = isolate->heap()->undefined_value();
if (isolate->has_pending_exception()) {
- isolate->pending_exception()->ToObject(&exception_object);
+ exception_object = isolate->pending_exception();
}
Handle<Object> exception_handle(exception_object, isolate);
@@ -154,24 +131,16 @@ Handle<String> MessageHandler::GetMessage(Isolate* isolate,
Factory* factory = isolate->factory();
Handle<String> fmt_str =
factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("FormatMessage"));
- Handle<JSFunction> fun =
- Handle<JSFunction>(
- JSFunction::cast(
- isolate->js_builtins_object()->
- GetPropertyNoExceptionThrown(*fmt_str)));
+ Handle<JSFunction> fun = Handle<JSFunction>::cast(Object::GetProperty(
+ isolate->js_builtins_object(), fmt_str).ToHandleChecked());
Handle<JSMessageObject> message = Handle<JSMessageObject>::cast(data);
Handle<Object> argv[] = { Handle<Object>(message->type(), isolate),
Handle<Object>(message->arguments(), isolate) };
- bool caught_exception;
- Handle<Object> result =
- Execution::TryCall(fun,
- isolate->js_builtins_object(),
- ARRAY_SIZE(argv),
- argv,
- &caught_exception);
-
- if (caught_exception || !result->IsString()) {
+ MaybeHandle<Object> maybe_result = Execution::TryCall(
+ fun, isolate->js_builtins_object(), ARRAY_SIZE(argv), argv);
+ Handle<Object> result;
+ if (!maybe_result.ToHandle(&result) || !result->IsString()) {
return factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("<error>"));
}
Handle<String> result_string = Handle<String>::cast(result);
@@ -180,7 +149,7 @@ Handle<String> MessageHandler::GetMessage(Isolate* isolate,
// here to improve the efficiency of converting it to a C string and
// other operations that are likely to take place (see GetLocalizedMessage
// for example).
- FlattenString(result_string);
+ result_string = String::Flatten(result_string);
return result_string;
}
diff --git a/deps/v8/src/messages.h b/deps/v8/src/messages.h
index 2f4be518b2..297160d988 100644
--- a/deps/v8/src/messages.h
+++ b/deps/v8/src/messages.h
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// The infrastructure used for (localized) message reporting in V8.
//
diff --git a/deps/v8/src/messages.js b/deps/v8/src/messages.js
index a389bb8fe5..1965da104e 100644
--- a/deps/v8/src/messages.js
+++ b/deps/v8/src/messages.js
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// -------------------------------------------------------------------
@@ -47,7 +24,8 @@ var kMessages = {
incompatible_method_receiver: ["Method ", "%0", " called on incompatible receiver ", "%1"],
multiple_defaults_in_switch: ["More than one default clause in switch statement"],
newline_after_throw: ["Illegal newline after throw"],
- redeclaration: ["%0", " '", "%1", "' has already been declared"],
+ label_redeclaration: ["Label '", "%0", "' has already been declared"],
+ var_redeclaration: ["Identifier '", "%0", "' has already been declared"],
no_catch_or_finally: ["Missing catch or finally after try"],
unknown_label: ["Undefined label '", "%0", "'"],
uncaught_exception: ["Uncaught ", "%0"],
@@ -99,6 +77,7 @@ var kMessages = {
observe_perform_non_string: ["Invalid non-string changeType"],
observe_perform_non_function: ["Cannot perform non-function"],
observe_notify_non_notifier: ["notify called on non-notifier object"],
+ observe_global_proxy: ["%0", " cannot be called on the global proxy object"],
not_typed_array: ["this is not a typed array."],
invalid_argument: ["invalid_argument"],
data_view_not_array_buffer: ["First argument to DataView constructor must be an ArrayBuffer"],
@@ -153,7 +132,8 @@ var kMessages = {
array_indexof_not_defined: ["Array.getIndexOf: Argument undefined"],
object_not_extensible: ["Can't add property ", "%0", ", object is not extensible"],
illegal_access: ["Illegal access"],
- invalid_preparser_data: ["Invalid preparser data for function ", "%0"],
+ invalid_cached_data_function: ["Invalid cached data for function ", "%0"],
+ invalid_cached_data: ["Invalid cached data"],
strict_mode_with: ["Strict mode code may not include a with statement"],
strict_eval_arguments: ["Unexpected eval or arguments in strict mode"],
too_many_arguments: ["Too many arguments in function call (only 65535 allowed)"],
@@ -198,8 +178,8 @@ function FormatString(format, args) {
try {
str = NoSideEffectToString(args[arg_num]);
if (str.length > 256) {
- str = %SubString(str, 0, 239) + "...<omitted>..." +
- %SubString(str, str.length - 2, str.length);
+ str = %_SubString(str, 0, 239) + "...<omitted>..." +
+ %_SubString(str, str.length - 2, str.length);
}
} catch (e) {
if (%IsJSModule(args[arg_num]))
@@ -1155,19 +1135,6 @@ function captureStackTrace(obj, cons_opt) {
stackTraceLimit);
var error_string = FormatErrorString(obj);
- // The holder of this getter ('obj') may not be the receiver ('this').
- // When this getter is called the first time, we use the context values to
- // format a stack trace string and turn this accessor pair into a data
- // property (on the holder).
- var getter = function() {
- // Stack is still a raw array awaiting to be formatted.
- var result = FormatStackTrace(obj, error_string, GetStackFrames(stack));
- // Turn this accessor into a data property.
- %DefineOrRedefineDataProperty(obj, 'stack', result, NONE);
- // Release context values.
- stack = error_string = UNDEFINED;
- return result;
- };
// Set the 'stack' property on the receiver. If the receiver is the same as
// holder of this setter, the accessor pair is turned into a data property.
@@ -1180,6 +1147,21 @@ function captureStackTrace(obj, cons_opt) {
}
};
+ // The holder of this getter ('obj') may not be the receiver ('this').
+ // When this getter is called the first time, we use the context values to
+ // format a stack trace string and turn this accessor pair into a data
+ // property (on the holder).
+ var getter = function() {
+ // Stack is still a raw array awaiting to be formatted.
+ var result = FormatStackTrace(obj, error_string, GetStackFrames(stack));
+ // Replace this accessor to return result directly.
+ %DefineOrRedefineAccessorProperty(
+ obj, 'stack', function() { return result }, setter, DONT_ENUM);
+ // Release context values.
+ stack = error_string = UNDEFINED;
+ return result;
+ };
+
%DefineOrRedefineAccessorProperty(obj, 'stack', getter, setter, DONT_ENUM);
}
@@ -1318,6 +1300,15 @@ function SetUpStackOverflowBoilerplate() {
var error_string = boilerplate.name + ": " + boilerplate.message;
+ // Set the 'stack' property on the receiver. If the receiver is the same as
+ // holder of this setter, the accessor pair is turned into a data property.
+ var setter = function(v) {
+ %DefineOrRedefineDataProperty(this, 'stack', v, NONE);
+ // Tentatively clear the hidden property. If the receiver is the same as
+ // holder, we release the raw stack trace this way.
+ %GetAndClearOverflowedStackTrace(this);
+ };
+
// The raw stack trace is stored as a hidden property on the holder of this
// getter, which may not be the same as the receiver. Find the holder to
// retrieve the raw stack trace and then turn this accessor pair into a
@@ -1333,20 +1324,12 @@ function SetUpStackOverflowBoilerplate() {
if (IS_UNDEFINED(stack)) return stack;
var result = FormatStackTrace(holder, error_string, GetStackFrames(stack));
- // Replace this accessor with a data property.
- %DefineOrRedefineDataProperty(holder, 'stack', result, NONE);
+ // Replace this accessor to return result directly.
+ %DefineOrRedefineAccessorProperty(
+ holder, 'stack', function() { return result }, setter, DONT_ENUM);
return result;
};
- // Set the 'stack' property on the receiver. If the receiver is the same as
- // holder of this setter, the accessor pair is turned into a data property.
- var setter = function(v) {
- %DefineOrRedefineDataProperty(this, 'stack', v, NONE);
- // Tentatively clear the hidden property. If the receiver is the same as
- // holder, we release the raw stack trace this way.
- %GetAndClearOverflowedStackTrace(this);
- };
-
%DefineOrRedefineAccessorProperty(
boilerplate, 'stack', getter, setter, DONT_ENUM);
diff --git a/deps/v8/src/mips/assembler-mips-inl.h b/deps/v8/src/mips/assembler-mips-inl.h
index f7f4354137..ba4c4f1348 100644
--- a/deps/v8/src/mips/assembler-mips-inl.h
+++ b/deps/v8/src/mips/assembler-mips-inl.h
@@ -255,7 +255,7 @@ void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode mode) {
}
-static const int kNoCodeAgeSequenceLength = 7;
+static const int kNoCodeAgeSequenceLength = 7 * Assembler::kInstrSize;
Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) {
@@ -361,14 +361,12 @@ void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
visitor->VisitExternalReference(this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
visitor->VisitCodeAgeSequence(this);
-#ifdef ENABLE_DEBUGGER_SUPPORT
} else if (((RelocInfo::IsJSReturn(mode) &&
IsPatchedReturnSequence()) ||
(RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence())) &&
isolate->debug()->has_break_points()) {
visitor->VisitDebugTarget(this);
-#endif
} else if (RelocInfo::IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this);
}
@@ -388,14 +386,12 @@ void RelocInfo::Visit(Heap* heap) {
StaticVisitor::VisitExternalReference(this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
StaticVisitor::VisitCodeAgeSequence(heap, this);
-#ifdef ENABLE_DEBUGGER_SUPPORT
} else if (heap->isolate()->debug()->has_break_points() &&
((RelocInfo::IsJSReturn(mode) &&
IsPatchedReturnSequence()) ||
(RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence()))) {
StaticVisitor::VisitDebugTarget(heap, this);
-#endif
} else if (RelocInfo::IsRuntimeEntry(mode)) {
StaticVisitor::VisitRuntimeEntry(this);
}
diff --git a/deps/v8/src/mips/assembler-mips.cc b/deps/v8/src/mips/assembler-mips.cc
index b659559fee..e629868e4e 100644
--- a/deps/v8/src/mips/assembler-mips.cc
+++ b/deps/v8/src/mips/assembler-mips.cc
@@ -102,10 +102,11 @@ const char* DoubleRegister::AllocationIndexToString(int index) {
}
-void CpuFeatures::Probe() {
+void CpuFeatures::Probe(bool serializer_enabled) {
unsigned standard_features = (OS::CpuFeaturesImpliedByPlatform() |
CpuFeaturesImpliedByCompiler());
- ASSERT(supported_ == 0 || supported_ == standard_features);
+ ASSERT(supported_ == 0 ||
+ (supported_ & standard_features) == standard_features);
#ifdef DEBUG
initialized_ = true;
#endif
@@ -115,7 +116,7 @@ void CpuFeatures::Probe() {
// snapshot.
supported_ |= standard_features;
- if (Serializer::enabled()) {
+ if (serializer_enabled) {
// No probing for features if we might serialize (generate snapshot).
return;
}
@@ -1655,10 +1656,12 @@ void Assembler::lwc1(FPURegister fd, const MemOperand& src) {
void Assembler::ldc1(FPURegister fd, const MemOperand& src) {
// Workaround for non-8-byte alignment of HeapNumber, convert 64-bit
// load to two 32-bit loads.
- GenInstrImmediate(LWC1, src.rm(), fd, src.offset_);
+ GenInstrImmediate(LWC1, src.rm(), fd, src.offset_ +
+ Register::kMantissaOffset);
FPURegister nextfpreg;
nextfpreg.setcode(fd.code() + 1);
- GenInstrImmediate(LWC1, src.rm(), nextfpreg, src.offset_ + 4);
+ GenInstrImmediate(LWC1, src.rm(), nextfpreg, src.offset_ +
+ Register::kExponentOffset);
}
@@ -1670,10 +1673,12 @@ void Assembler::swc1(FPURegister fd, const MemOperand& src) {
void Assembler::sdc1(FPURegister fd, const MemOperand& src) {
// Workaround for non-8-byte alignment of HeapNumber, convert 64-bit
// store to two 32-bit stores.
- GenInstrImmediate(SWC1, src.rm(), fd, src.offset_);
+ GenInstrImmediate(SWC1, src.rm(), fd, src.offset_ +
+ Register::kMantissaOffset);
FPURegister nextfpreg;
nextfpreg.setcode(fd.code() + 1);
- GenInstrImmediate(SWC1, src.rm(), nextfpreg, src.offset_ + 4);
+ GenInstrImmediate(SWC1, src.rm(), nextfpreg, src.offset_ +
+ Register::kExponentOffset);
}
@@ -2075,12 +2080,7 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
if (!RelocInfo::IsNone(rinfo.rmode())) {
// Don't record external references unless the heap will be serialized.
if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
-#ifdef DEBUG
- if (!Serializer::enabled()) {
- Serializer::TooLateToEnableNow();
- }
-#endif
- if (!Serializer::enabled() && !emit_debug_code()) {
+ if (!Serializer::enabled(isolate()) && !emit_debug_code()) {
return;
}
}
@@ -2328,16 +2328,17 @@ void Assembler::JumpLabelToJumpRegister(Address pc) {
}
-MaybeObject* Assembler::AllocateConstantPool(Heap* heap) {
+Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
// No out-of-line constant pool support.
- UNREACHABLE();
- return NULL;
+ ASSERT(!FLAG_enable_ool_constant_pool);
+ return isolate->factory()->empty_constant_pool_array();
}
void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
// No out-of-line constant pool support.
- UNREACHABLE();
+ ASSERT(!FLAG_enable_ool_constant_pool);
+ return;
}
diff --git a/deps/v8/src/mips/assembler-mips.h b/deps/v8/src/mips/assembler-mips.h
index ea956e1355..860097c8af 100644
--- a/deps/v8/src/mips/assembler-mips.h
+++ b/deps/v8/src/mips/assembler-mips.h
@@ -77,6 +77,16 @@ struct Register {
static const int kSizeInBytes = 4;
static const int kCpRegister = 23; // cp (s7) is the 23rd register.
+#if defined(V8_TARGET_LITTLE_ENDIAN)
+ static const int kMantissaOffset = 0;
+ static const int kExponentOffset = 4;
+#elif defined(V8_TARGET_BIG_ENDIAN)
+ static const int kMantissaOffset = 4;
+ static const int kExponentOffset = 0;
+#else
+#error Unknown endianness
+#endif
+
inline static int NumAllocatableRegisters();
static int ToAllocationIndex(Register reg) {
@@ -415,7 +425,10 @@ class CpuFeatures : public AllStatic {
public:
// Detect features of the target CPU. Set safe defaults if the serializer
// is enabled (snapshots must be portable).
- static void Probe();
+ static void Probe(bool serializer_enabled);
+
+ // A special case for printing target and features, which we want to do
+ // before initializing the isolate
// Check whether a feature is supported by the target CPU.
static bool IsSupported(CpuFeature f) {
@@ -423,15 +436,11 @@ class CpuFeatures : public AllStatic {
return Check(f, supported_);
}
- static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
- ASSERT(initialized_);
- return Check(f, found_by_runtime_probing_only_);
- }
-
- static bool IsSafeForSnapshot(CpuFeature f) {
+ static bool IsSafeForSnapshot(Isolate* isolate, CpuFeature f) {
return Check(f, cross_compile_) ||
(IsSupported(f) &&
- (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
+ !(Serializer::enabled(isolate) &&
+ Check(f, found_by_runtime_probing_only_)));
}
static bool VerifyCrossCompiling() {
@@ -444,6 +453,8 @@ class CpuFeatures : public AllStatic {
(cross_compile_ & mask) == mask;
}
+ static bool SupportsCrankshaft() { return CpuFeatures::IsSupported(FPU); }
+
private:
static bool Check(CpuFeature f, unsigned set) {
return (set & flag2set(f)) != 0;
@@ -1007,7 +1018,7 @@ class Assembler : public AssemblerBase {
void CheckTrampolinePool();
// Allocate a constant pool of the correct size for the generated code.
- MaybeObject* AllocateConstantPool(Heap* heap);
+ Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate);
// Generate the constant pool for the generated code.
void PopulateConstantPool(ConstantPoolArray* constant_pool);
diff --git a/deps/v8/src/mips/builtins-mips.cc b/deps/v8/src/mips/builtins-mips.cc
index 03d6cc80d6..fdd062b6b6 100644
--- a/deps/v8/src/mips/builtins-mips.cc
+++ b/deps/v8/src/mips/builtins-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
@@ -391,13 +368,11 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
// the preconditions is not met, the code bails out to the runtime call.
if (FLAG_inline_new) {
Label undo_allocation;
-#ifdef ENABLE_DEBUGGER_SUPPORT
ExternalReference debug_step_in_fp =
ExternalReference::debug_step_in_fp_address(isolate);
__ li(a2, Operand(debug_step_in_fp));
__ lw(a2, MemOperand(a2));
__ Branch(&rt_call, ne, a2, Operand(zero_reg));
-#endif
// Load the initial map and verify that it is in fact a map.
// a1: constructor function
@@ -470,9 +445,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
if (count_constructions) {
__ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
- __ lw(a0, FieldMemOperand(a2, Map::kInstanceSizesOffset));
- __ Ext(a0, a0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte,
- kBitsPerByte);
+ __ lbu(a0, FieldMemOperand(a2, Map::kPreAllocatedPropertyFieldsOffset));
__ sll(at, a0, kPointerSizeLog2);
__ addu(a0, t5, at);
__ sll(at, a3, kPointerSizeLog2);
@@ -525,12 +498,9 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
__ lbu(a3, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset));
// The field instance sizes contains both pre-allocated property fields
// and in-object properties.
- __ lw(a0, FieldMemOperand(a2, Map::kInstanceSizesOffset));
- __ Ext(t6, a0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte,
- kBitsPerByte);
+ __ lbu(t6, FieldMemOperand(a2, Map::kPreAllocatedPropertyFieldsOffset));
__ Addu(a3, a3, Operand(t6));
- __ Ext(t6, a0, Map::kInObjectPropertiesByte * kBitsPerByte,
- kBitsPerByte);
+ __ lbu(t6, FieldMemOperand(a2, Map::kInObjectPropertiesOffset));
__ subu(a3, a3, t6);
// Done if no extra properties are to be allocated.
@@ -829,7 +799,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
if (is_construct) {
// No type feedback cell is available
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
- CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
+ CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
ParameterCount actual(a0);
@@ -895,7 +865,7 @@ static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
// Set a0 to point to the head of the PlatformCodeAge sequence.
__ Subu(a0, a0,
- Operand((kNoCodeAgeSequenceLength - 1) * Assembler::kInstrSize));
+ Operand(kNoCodeAgeSequenceLength - Assembler::kInstrSize));
// The following registers must be saved and restored when calling through to
// the runtime:
@@ -934,7 +904,7 @@ void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
// Set a0 to point to the head of the PlatformCodeAge sequence.
__ Subu(a0, a0,
- Operand((kNoCodeAgeSequenceLength - 1) * Assembler::kInstrSize));
+ Operand(kNoCodeAgeSequenceLength - Assembler::kInstrSize));
// The following registers must be saved and restored when calling through to
// the runtime:
@@ -956,7 +926,7 @@ void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
__ Addu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
// Jump to point after the code-age stub.
- __ Addu(a0, a0, Operand((kNoCodeAgeSequenceLength) * Assembler::kInstrSize));
+ __ Addu(a0, a0, Operand(kNoCodeAgeSequenceLength));
__ Jump(a0);
}
@@ -1305,7 +1275,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// Out of stack space.
__ lw(a1, MemOperand(fp, kFunctionOffset));
__ Push(a1, v0);
- __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
+ __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
// End of stack check.
// Push current limit and index.
@@ -1426,6 +1396,27 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
}
+static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
+ Label* stack_overflow) {
+ // ----------- S t a t e -------------
+ // -- a0 : actual number of arguments
+ // -- a1 : function (passed through to callee)
+ // -- a2 : expected number of arguments
+ // -----------------------------------
+ // Check the stack for overflow. We are not trying to catch
+ // interruptions (e.g. debug break and preemption) here, so the "real stack
+ // limit" is checked.
+ __ LoadRoot(t1, Heap::kRealStackLimitRootIndex);
+ // Make t1 the space we have left. The stack might already be overflowed
+ // here which will cause t1 to become negative.
+ __ subu(t1, sp, t1);
+ // Check if the arguments will overflow the stack.
+ __ sll(at, a2, kPointerSizeLog2);
+ // Signed comparison.
+ __ Branch(stack_overflow, le, t1, Operand(at));
+}
+
+
static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
__ sll(a0, a0, kSmiTagSize);
__ li(t0, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
@@ -1460,6 +1451,8 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// -- a2: expected arguments count
// -----------------------------------
+ Label stack_overflow;
+ ArgumentAdaptorStackCheck(masm, &stack_overflow);
Label invoke, dont_adapt_arguments;
Label enough, too_few;
@@ -1568,6 +1561,14 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// -------------------------------------------
__ bind(&dont_adapt_arguments);
__ Jump(a3);
+
+ __ bind(&stack_overflow);
+ {
+ FrameScope frame(masm, StackFrame::MANUAL);
+ EnterArgumentsAdaptorFrame(masm);
+ __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
+ __ break_(0xCC);
+ }
}
diff --git a/deps/v8/src/mips/code-stubs-mips.cc b/deps/v8/src/mips/code-stubs-mips.cc
index 332ed4b6ab..79af21940c 100644
--- a/deps/v8/src/mips/code-stubs-mips.cc
+++ b/deps/v8/src/mips/code-stubs-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -40,7 +17,6 @@ namespace internal {
void FastNewClosureStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a2 };
descriptor->register_param_count_ = 1;
@@ -51,7 +27,6 @@ void FastNewClosureStub::InitializeInterfaceDescriptor(
void FastNewContextStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1 };
descriptor->register_param_count_ = 1;
@@ -61,7 +36,6 @@ void FastNewContextStub::InitializeInterfaceDescriptor(
void ToNumberStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0 };
descriptor->register_param_count_ = 1;
@@ -71,7 +45,6 @@ void ToNumberStub::InitializeInterfaceDescriptor(
void NumberToStringStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0 };
descriptor->register_param_count_ = 1;
@@ -82,7 +55,6 @@ void NumberToStringStub::InitializeInterfaceDescriptor(
void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a3, a2, a1 };
descriptor->register_param_count_ = 3;
@@ -94,7 +66,6 @@ void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a3, a2, a1, a0 };
descriptor->register_param_count_ = 4;
@@ -105,7 +76,6 @@ void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a2, a3 };
descriptor->register_param_count_ = 2;
@@ -115,7 +85,6 @@ void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1, a0 };
descriptor->register_param_count_ = 2;
@@ -126,7 +95,6 @@ void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = {a1, a0 };
descriptor->register_param_count_ = 2;
@@ -137,7 +105,6 @@ void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
void RegExpConstructResultStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a2, a1, a0 };
descriptor->register_param_count_ = 3;
@@ -148,7 +115,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor(
void LoadFieldStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0 };
descriptor->register_param_count_ = 1;
@@ -158,7 +124,6 @@ void LoadFieldStub::InitializeInterfaceDescriptor(
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1 };
descriptor->register_param_count_ = 1;
@@ -168,7 +133,6 @@ void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
void StringLengthStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0, a2 };
descriptor->register_param_count_ = 2;
@@ -178,7 +142,6 @@ void StringLengthStub::InitializeInterfaceDescriptor(
void KeyedStringLengthStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1, a0 };
descriptor->register_param_count_ = 2;
@@ -188,7 +151,6 @@ void KeyedStringLengthStub::InitializeInterfaceDescriptor(
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a2, a1, a0 };
descriptor->register_param_count_ = 3;
@@ -199,7 +161,6 @@ void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
void TransitionElementsKindStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0, a1 };
descriptor->register_param_count_ = 2;
@@ -211,7 +172,6 @@ void TransitionElementsKindStub::InitializeInterfaceDescriptor(
void CompareNilICStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0 };
descriptor->register_param_count_ = 1;
@@ -219,12 +179,11 @@ void CompareNilICStub::InitializeInterfaceDescriptor(
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(CompareNilIC_Miss);
descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate));
+ ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate()));
}
static void InitializeArrayConstructorDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor,
int constant_stack_parameter_count) {
// register state
@@ -253,7 +212,6 @@ static void InitializeArrayConstructorDescriptor(
static void InitializeInternalArrayConstructorDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor,
int constant_stack_parameter_count) {
// register state
@@ -281,28 +239,24 @@ static void InitializeInternalArrayConstructorDescriptor(
void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(isolate, descriptor, 0);
+ InitializeArrayConstructorDescriptor(descriptor, 0);
}
void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(isolate, descriptor, 1);
+ InitializeArrayConstructorDescriptor(descriptor, 1);
}
void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(isolate, descriptor, -1);
+ InitializeArrayConstructorDescriptor(descriptor, -1);
}
void ToBooleanStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0 };
descriptor->register_param_count_ = 1;
@@ -310,33 +264,29 @@ void ToBooleanStub::InitializeInterfaceDescriptor(
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(ToBooleanIC_Miss);
descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate));
+ ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate()));
}
void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 0);
+ InitializeInternalArrayConstructorDescriptor(descriptor, 0);
}
void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 1);
+ InitializeInternalArrayConstructorDescriptor(descriptor, 1);
}
void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(isolate, descriptor, -1);
+ InitializeInternalArrayConstructorDescriptor(descriptor, -1);
}
void StoreGlobalStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1, a2, a0 };
descriptor->register_param_count_ = 3;
@@ -347,7 +297,6 @@ void StoreGlobalStub::InitializeInterfaceDescriptor(
void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0, a3, a1, a2 };
descriptor->register_param_count_ = 4;
@@ -358,19 +307,17 @@ void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
void BinaryOpICStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1, a0 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate));
+ ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate()));
}
void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a2, a1, a0 };
descriptor->register_param_count_ = 3;
@@ -381,7 +328,6 @@ void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
void StringAddStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1, a0 };
descriptor->register_param_count_ = 2;
@@ -494,10 +440,9 @@ static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm,
void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
// Update the static counter each time a new code stub is generated.
- Isolate* isolate = masm->isolate();
- isolate->counters()->code_stubs()->Increment();
+ isolate()->counters()->code_stubs()->Increment();
- CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate);
+ CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor();
int param_count = descriptor->register_param_count_;
{
// Call the runtime system in a fresh internal frame.
@@ -526,11 +471,13 @@ void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
// stub so you don't have to set up the frame.
class ConvertToDoubleStub : public PlatformCodeStub {
public:
- ConvertToDoubleStub(Register result_reg_1,
+ ConvertToDoubleStub(Isolate* isolate,
+ Register result_reg_1,
Register result_reg_2,
Register source_reg,
Register scratch_reg)
- : result1_(result_reg_1),
+ : PlatformCodeStub(isolate),
+ result1_(result_reg_1),
result2_(result_reg_2),
source_(source_reg),
zeros_(scratch_reg) { }
@@ -559,13 +506,14 @@ class ConvertToDoubleStub : public PlatformCodeStub {
void ConvertToDoubleStub::Generate(MacroAssembler* masm) {
-#ifndef BIG_ENDIAN_FLOATING_POINT
- Register exponent = result1_;
- Register mantissa = result2_;
-#else
- Register exponent = result2_;
- Register mantissa = result1_;
-#endif
+ Register exponent, mantissa;
+ if (kArchEndian == kLittle) {
+ exponent = result1_;
+ mantissa = result2_;
+ } else {
+ exponent = result2_;
+ mantissa = result1_;
+ }
Label not_special;
// Convert from Smi to integer.
__ sra(source_, source_, kSmiTagSize);
@@ -671,8 +619,10 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
Register input_high = scratch2;
Register input_low = scratch3;
- __ lw(input_low, MemOperand(input_reg, double_offset));
- __ lw(input_high, MemOperand(input_reg, double_offset + kIntSize));
+ __ lw(input_low,
+ MemOperand(input_reg, double_offset + Register::kMantissaOffset));
+ __ lw(input_high,
+ MemOperand(input_reg, double_offset + Register::kExponentOffset));
Label normal_exponent, restore_sign;
// Extract the biased exponent in result.
@@ -758,10 +708,10 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
void WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(
Isolate* isolate) {
- WriteInt32ToHeapNumberStub stub1(a1, v0, a2, a3);
- WriteInt32ToHeapNumberStub stub2(a2, v0, a3, a0);
- stub1.GetCode(isolate);
- stub2.GetCode(isolate);
+ WriteInt32ToHeapNumberStub stub1(isolate, a1, v0, a2, a3);
+ WriteInt32ToHeapNumberStub stub2(isolate, a2, v0, a3, a0);
+ stub1.GetCode();
+ stub2.GetCode();
}
@@ -1151,8 +1101,6 @@ void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
// f12, f14 are the double representations of the left hand side
// and the right hand side if we have FPU. Otherwise a2, a3 represent
// left hand side and a0, a1 represent right hand side.
-
- Isolate* isolate = masm->isolate();
Label nan;
__ li(t0, Operand(LESS));
__ li(t1, Operand(GREATER));
@@ -1227,7 +1175,8 @@ void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
__ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, a2, a3, &slow);
- __ IncrementCounter(isolate->counters()->string_compare_native(), 1, a2, a3);
+ __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, a2,
+ a3);
if (cc == eq) {
StringCompareStub::GenerateFlatAsciiStringEquals(masm,
lhs,
@@ -1315,9 +1264,9 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
AllowExternalCallThatCantCauseGC scope(masm);
__ PrepareCallCFunction(argument_count, fp_argument_count, scratch);
- __ li(a0, Operand(ExternalReference::isolate_address(masm->isolate())));
+ __ li(a0, Operand(ExternalReference::isolate_address(isolate())));
__ CallCFunction(
- ExternalReference::store_buffer_overflow_function(masm->isolate()),
+ ExternalReference::store_buffer_overflow_function(isolate()),
argument_count);
if (save_doubles_ == kSaveFPRegs) {
__ MultiPopFPU(kCallerSavedFPU);
@@ -1446,7 +1395,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ PrepareCallCFunction(0, 2, scratch2);
__ MovToFloatParameters(double_base, double_exponent);
__ CallCFunction(
- ExternalReference::power_double_double_function(masm->isolate()),
+ ExternalReference::power_double_double_function(isolate()),
0, 2);
}
__ pop(ra);
@@ -1507,11 +1456,11 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ cvt_d_w(double_exponent, single_scratch);
// Returning or bailing out.
- Counters* counters = masm->isolate()->counters();
+ Counters* counters = isolate()->counters();
if (exponent_type_ == ON_STACK) {
// The arguments are still on the stack.
__ bind(&call_runtime);
- __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
+ __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1);
// The stub is called from non-optimized code, which expects the result
// as heap number in exponent.
@@ -1530,7 +1479,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ PrepareCallCFunction(0, 2, scratch);
__ MovToFloatParameters(double_base, double_exponent);
__ CallCFunction(
- ExternalReference::power_double_double_function(masm->isolate()),
+ ExternalReference::power_double_double_function(isolate()),
0, 2);
}
__ pop(ra);
@@ -1564,77 +1513,75 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
void StoreRegistersStateStub::GenerateAheadOfTime(
Isolate* isolate) {
- StoreRegistersStateStub stub1(kDontSaveFPRegs);
- stub1.GetCode(isolate);
+ StoreRegistersStateStub stub1(isolate, kDontSaveFPRegs);
+ stub1.GetCode();
// Hydrogen code stubs need stub2 at snapshot time.
- StoreRegistersStateStub stub2(kSaveFPRegs);
- stub2.GetCode(isolate);
+ StoreRegistersStateStub stub2(isolate, kSaveFPRegs);
+ stub2.GetCode();
}
void RestoreRegistersStateStub::GenerateAheadOfTime(
Isolate* isolate) {
- RestoreRegistersStateStub stub1(kDontSaveFPRegs);
- stub1.GetCode(isolate);
+ RestoreRegistersStateStub stub1(isolate, kDontSaveFPRegs);
+ stub1.GetCode();
// Hydrogen code stubs need stub2 at snapshot time.
- RestoreRegistersStateStub stub2(kSaveFPRegs);
- stub2.GetCode(isolate);
+ RestoreRegistersStateStub stub2(isolate, kSaveFPRegs);
+ stub2.GetCode();
}
void CodeStub::GenerateFPStubs(Isolate* isolate) {
SaveFPRegsMode mode = kSaveFPRegs;
- CEntryStub save_doubles(1, mode);
- StoreBufferOverflowStub stub(mode);
+ CEntryStub save_doubles(isolate, 1, mode);
+ StoreBufferOverflowStub stub(isolate, mode);
// These stubs might already be in the snapshot, detect that and don't
// regenerate, which would lead to code stub initialization state being messed
// up.
Code* save_doubles_code;
- if (!save_doubles.FindCodeInCache(&save_doubles_code, isolate)) {
- save_doubles_code = *save_doubles.GetCode(isolate);
+ if (!save_doubles.FindCodeInCache(&save_doubles_code)) {
+ save_doubles_code = *save_doubles.GetCode();
}
Code* store_buffer_overflow_code;
- if (!stub.FindCodeInCache(&store_buffer_overflow_code, isolate)) {
- store_buffer_overflow_code = *stub.GetCode(isolate);
+ if (!stub.FindCodeInCache(&store_buffer_overflow_code)) {
+ store_buffer_overflow_code = *stub.GetCode();
}
isolate->set_fp_stubs_generated(true);
}
void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
- CEntryStub stub(1, kDontSaveFPRegs);
- stub.GetCode(isolate);
+ CEntryStub stub(isolate, 1, kDontSaveFPRegs);
+ stub.GetCode();
}
-void CEntryStub::GenerateCore(MacroAssembler* masm,
- Label* throw_normal_exception,
- Label* throw_termination_exception,
- bool do_gc,
- bool always_allocate) {
- // v0: result parameter for PerformGC, if any
- // s0: number of arguments including receiver (C callee-saved)
- // s1: pointer to the first argument (C callee-saved)
- // s2: pointer to builtin function (C callee-saved)
+void CEntryStub::Generate(MacroAssembler* masm) {
+ // Called from JavaScript; parameters are on stack as if calling JS function
+ // s0: number of arguments including receiver
+ // s1: size of arguments excluding receiver
+ // s2: pointer to builtin function
+ // fp: frame pointer (restored after C call)
+ // sp: stack pointer (restored as callee's sp after C call)
+ // cp: current context (C callee-saved)
- Isolate* isolate = masm->isolate();
+ ProfileEntryHookStub::MaybeCallEntryHook(masm);
- if (do_gc) {
- // Move result passed in v0 into a0 to call PerformGC.
- __ mov(a0, v0);
- __ PrepareCallCFunction(2, 0, a1);
- __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate())));
- __ CallCFunction(ExternalReference::perform_gc_function(isolate), 2, 0);
- }
+ // NOTE: s0-s2 hold the arguments of this function instead of a0-a2.
+ // The reason for this is that these arguments would need to be saved anyway
+ // so it's faster to set them up directly.
+ // See MacroAssembler::PrepareCEntryArgs and PrepareCEntryFunction.
- ExternalReference scope_depth =
- ExternalReference::heap_always_allocate_scope_depth(isolate);
- if (always_allocate) {
- __ li(a0, Operand(scope_depth));
- __ lw(a1, MemOperand(a0));
- __ Addu(a1, a1, Operand(1));
- __ sw(a1, MemOperand(a0));
- }
+ // Compute the argv pointer in a callee-saved register.
+ __ Addu(s1, sp, s1);
+
+ // Enter the exit frame that transitions from JavaScript to C++.
+ FrameScope scope(masm, StackFrame::MANUAL);
+ __ EnterExitFrame(save_doubles_);
+
+ // s0: number of arguments including receiver (C callee-saved)
+ // s1: pointer to first argument (C callee-saved)
+ // s2: pointer to builtin function (C callee-saved)
// Prepare arguments for C routine.
// a0 = argc
@@ -1646,7 +1593,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
__ AssertStackIsAligned();
- __ li(a2, Operand(ExternalReference::isolate_address(isolate)));
+ __ li(a2, Operand(ExternalReference::isolate_address(isolate())));
// To let the GC traverse the return address of the exit frames, we need to
// know where the return address is. The CEntryStub is unmovable, so
@@ -1681,130 +1628,67 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
masm->InstructionsGeneratedSince(&find_ra));
}
- if (always_allocate) {
- // It's okay to clobber a2 and a3 here. v0 & v1 contain result.
- __ li(a2, Operand(scope_depth));
- __ lw(a3, MemOperand(a2));
- __ Subu(a3, a3, Operand(1));
- __ sw(a3, MemOperand(a2));
+
+ // Runtime functions should not return 'the hole'. Allowing it to escape may
+ // lead to crashes in the IC code later.
+ if (FLAG_debug_code) {
+ Label okay;
+ __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
+ __ Branch(&okay, ne, v0, Operand(t0));
+ __ stop("The hole escaped");
+ __ bind(&okay);
}
- // Check for failure result.
- Label failure_returned;
- STATIC_ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0);
- __ addiu(a2, v0, 1);
- __ andi(t0, a2, kFailureTagMask);
- __ Branch(USE_DELAY_SLOT, &failure_returned, eq, t0, Operand(zero_reg));
- // Restore stack (remove arg slots) in branch delay slot.
- __ addiu(sp, sp, kCArgsSlotsSize);
+ // Check result for exception sentinel.
+ Label exception_returned;
+ __ LoadRoot(t0, Heap::kExceptionRootIndex);
+ __ Branch(&exception_returned, eq, t0, Operand(v0));
+
+ ExternalReference pending_exception_address(
+ Isolate::kPendingExceptionAddress, isolate());
+ // Check that there is no pending exception, otherwise we
+ // should have returned the exception sentinel.
+ if (FLAG_debug_code) {
+ Label okay;
+ __ li(a2, Operand(pending_exception_address));
+ __ lw(a2, MemOperand(a2));
+ __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
+ // Cannot use check here as it attempts to generate call into runtime.
+ __ Branch(&okay, eq, t0, Operand(a2));
+ __ stop("Unexpected pending exception");
+ __ bind(&okay);
+ }
// Exit C frame and return.
// v0:v1: result
// sp: stack pointer
// fp: frame pointer
+ // s0: still holds argc (callee-saved).
__ LeaveExitFrame(save_doubles_, s0, true, EMIT_RETURN);
- // Check if we should retry or throw exception.
- Label retry;
- __ bind(&failure_returned);
- STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0);
- __ andi(t0, v0, ((1 << kFailureTypeTagSize) - 1) << kFailureTagSize);
- __ Branch(&retry, eq, t0, Operand(zero_reg));
+ // Handling of exception.
+ __ bind(&exception_returned);
// Retrieve the pending exception.
- __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
- isolate)));
- __ lw(v0, MemOperand(t0));
+ __ li(a2, Operand(pending_exception_address));
+ __ lw(v0, MemOperand(a2));
// Clear the pending exception.
- __ li(a3, Operand(isolate->factory()->the_hole_value()));
- __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
- isolate)));
- __ sw(a3, MemOperand(t0));
+ __ li(a3, Operand(isolate()->factory()->the_hole_value()));
+ __ sw(a3, MemOperand(a2));
// Special handling of termination exceptions which are uncatchable
// by javascript code.
+ Label throw_termination_exception;
__ LoadRoot(t0, Heap::kTerminationExceptionRootIndex);
- __ Branch(throw_termination_exception, eq, v0, Operand(t0));
+ __ Branch(&throw_termination_exception, eq, v0, Operand(t0));
// Handle normal exception.
- __ jmp(throw_normal_exception);
-
- __ bind(&retry);
- // Last failure (v0) will be moved to (a0) for parameter when retrying.
-}
-
-
-void CEntryStub::Generate(MacroAssembler* masm) {
- // Called from JavaScript; parameters are on stack as if calling JS function
- // s0: number of arguments including receiver
- // s1: size of arguments excluding receiver
- // s2: pointer to builtin function
- // fp: frame pointer (restored after C call)
- // sp: stack pointer (restored as callee's sp after C call)
- // cp: current context (C callee-saved)
-
- ProfileEntryHookStub::MaybeCallEntryHook(masm);
-
- // NOTE: Invocations of builtins may return failure objects
- // instead of a proper result. The builtin entry handles
- // this by performing a garbage collection and retrying the
- // builtin once.
-
- // NOTE: s0-s2 hold the arguments of this function instead of a0-a2.
- // The reason for this is that these arguments would need to be saved anyway
- // so it's faster to set them up directly.
- // See MacroAssembler::PrepareCEntryArgs and PrepareCEntryFunction.
-
- // Compute the argv pointer in a callee-saved register.
- __ Addu(s1, sp, s1);
-
- // Enter the exit frame that transitions from JavaScript to C++.
- FrameScope scope(masm, StackFrame::MANUAL);
- __ EnterExitFrame(save_doubles_);
-
- // s0: number of arguments (C callee-saved)
- // s1: pointer to first argument (C callee-saved)
- // s2: pointer to builtin function (C callee-saved)
-
- Label throw_normal_exception;
- Label throw_termination_exception;
-
- // Call into the runtime system.
- GenerateCore(masm,
- &throw_normal_exception,
- &throw_termination_exception,
- false,
- false);
-
- // Do space-specific GC and retry runtime call.
- GenerateCore(masm,
- &throw_normal_exception,
- &throw_termination_exception,
- true,
- false);
-
- // Do full GC and retry runtime call one final time.
- Failure* failure = Failure::InternalError();
- __ li(v0, Operand(reinterpret_cast<int32_t>(failure)));
- GenerateCore(masm,
- &throw_normal_exception,
- &throw_termination_exception,
- true,
- true);
-
- { FrameScope scope(masm, StackFrame::MANUAL);
- __ PrepareCallCFunction(0, v0);
- __ CallCFunction(
- ExternalReference::out_of_memory_function(masm->isolate()), 0);
- }
+ __ Throw(v0);
__ bind(&throw_termination_exception);
__ ThrowUncatchable(v0);
-
- __ bind(&throw_normal_exception);
- __ Throw(v0);
}
@@ -1896,7 +1780,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
__ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
isolate)));
__ sw(v0, MemOperand(t0)); // We come back from 'invoke'. result is in v0.
- __ li(v0, Operand(reinterpret_cast<int32_t>(Failure::Exception())));
+ __ LoadRoot(v0, Heap::kExceptionRootIndex);
__ b(&exit); // b exposes branch delay slot.
__ nop(); // Branch delay slot nop.
@@ -2121,7 +2005,7 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
__ Branch(&object_not_null,
ne,
scratch,
- Operand(masm->isolate()->factory()->null_value()));
+ Operand(isolate()->factory()->null_value()));
__ li(v0, Operand(Smi::FromInt(1)));
__ DropAndRet(HasArgsInRegisters() ? 0 : 2);
@@ -2169,7 +2053,7 @@ void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
// -- a1 : receiver
// -----------------------------------
__ Branch(&miss, ne, a0,
- Operand(masm->isolate()->factory()->prototype_string()));
+ Operand(isolate()->factory()->prototype_string()));
receiver = a1;
} else {
ASSERT(kind() == Code::LOAD_IC);
@@ -2610,8 +2494,6 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
const int kSubjectOffset = 2 * kPointerSize;
const int kJSRegExpOffset = 3 * kPointerSize;
- Isolate* isolate = masm->isolate();
-
Label runtime;
// Allocation of registers for this function. These are in callee save
// registers and will be preserved by the call to the native RegExp code, as
@@ -2626,9 +2508,9 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Ensure that a RegExp stack is allocated.
ExternalReference address_of_regexp_stack_memory_address =
ExternalReference::address_of_regexp_stack_memory_address(
- isolate);
+ isolate());
ExternalReference address_of_regexp_stack_memory_size =
- ExternalReference::address_of_regexp_stack_memory_size(isolate);
+ ExternalReference::address_of_regexp_stack_memory_size(isolate());
__ li(a0, Operand(address_of_regexp_stack_memory_size));
__ lw(a0, MemOperand(a0, 0));
__ Branch(&runtime, eq, a0, Operand(zero_reg));
@@ -2775,7 +2657,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// subject: Subject string
// regexp_data: RegExp data (FixedArray)
// All checks done. Now push arguments for native regexp code.
- __ IncrementCounter(isolate->counters()->regexp_entry_native(),
+ __ IncrementCounter(isolate()->counters()->regexp_entry_native(),
1, a0, a2);
// Isolates: note we add an additional parameter here (isolate pointer).
@@ -2799,7 +2681,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Argument 9: Pass current isolate address.
// CFunctionArgumentOperand handles MIPS stack argument slots.
- __ li(a0, Operand(ExternalReference::isolate_address(isolate)));
+ __ li(a0, Operand(ExternalReference::isolate_address(isolate())));
__ sw(a0, MemOperand(sp, 5 * kPointerSize));
// Argument 8: Indicate that this is a direct call from JavaScript.
@@ -2821,7 +2703,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Argument 5: static offsets vector buffer.
__ li(a0, Operand(
- ExternalReference::address_of_static_offsets_vector(isolate)));
+ ExternalReference::address_of_static_offsets_vector(isolate())));
__ sw(a0, MemOperand(sp, 1 * kPointerSize));
// For arguments 4 and 3 get string length, calculate start of string data
@@ -2854,7 +2736,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Locate the code entry and call it.
__ Addu(t9, t9, Operand(Code::kHeaderSize - kHeapObjectTag));
- DirectCEntryStub stub;
+ DirectCEntryStub stub(isolate());
stub.GenerateCall(masm, t9);
__ LeaveExitFrame(false, no_reg, true);
@@ -2876,9 +2758,9 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// stack overflow (on the backtrack stack) was detected in RegExp code but
// haven't created the exception yet. Handle that in the runtime system.
// TODO(592): Rerunning the RegExp to get the stack overflow exception.
- __ li(a1, Operand(isolate->factory()->the_hole_value()));
+ __ li(a1, Operand(isolate()->factory()->the_hole_value()));
__ li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
- isolate)));
+ isolate())));
__ lw(v0, MemOperand(a2, 0));
__ Branch(&runtime, eq, v0, Operand(a1));
@@ -2896,7 +2778,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ bind(&failure);
// For failure and exception return null.
- __ li(v0, Operand(isolate->factory()->null_value()));
+ __ li(v0, Operand(isolate()->factory()->null_value()));
__ DropAndRet(4);
// Process the result from the native regexp code.
@@ -2957,7 +2839,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Get the static offsets vector filled by the native regexp code.
ExternalReference address_of_static_offsets_vector =
- ExternalReference::address_of_static_offsets_vector(isolate);
+ ExternalReference::address_of_static_offsets_vector(isolate());
__ li(a2, Operand(address_of_static_offsets_vector));
// a1: number of capture registers
@@ -3110,7 +2992,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
__ SmiTag(a0);
__ MultiPush(kSavedRegs);
- CreateAllocationSiteStub create_stub;
+ CreateAllocationSiteStub create_stub(masm->isolate());
__ CallStub(&create_stub);
__ MultiPop(kSavedRegs);
@@ -3135,11 +3017,61 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
}
+static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
+ __ lw(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
+ __ lw(t0, FieldMemOperand(a3, SharedFunctionInfo::kCompilerHintsOffset));
+
+ // Do not transform the receiver for strict mode functions.
+ int32_t strict_mode_function_mask =
+ 1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize);
+ // Do not transform the receiver for native (Compilerhints already in a3).
+ int32_t native_mask = 1 << (SharedFunctionInfo::kNative + kSmiTagSize);
+ __ And(at, t0, Operand(strict_mode_function_mask | native_mask));
+ __ Branch(cont, ne, at, Operand(zero_reg));
+}
+
+
+static void EmitSlowCase(MacroAssembler* masm,
+ int argc,
+ Label* non_function) {
+ // Check for function proxy.
+ __ Branch(non_function, ne, t0, Operand(JS_FUNCTION_PROXY_TYPE));
+ __ push(a1); // put proxy as additional argument
+ __ li(a0, Operand(argc + 1, RelocInfo::NONE32));
+ __ mov(a2, zero_reg);
+ __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY);
+ {
+ Handle<Code> adaptor =
+ masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
+ __ Jump(adaptor, RelocInfo::CODE_TARGET);
+ }
+
+ // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
+ // of the original receiver from the call site).
+ __ bind(non_function);
+ __ sw(a1, MemOperand(sp, argc * kPointerSize));
+ __ li(a0, Operand(argc)); // Set up the number of arguments.
+ __ mov(a2, zero_reg);
+ __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION);
+ __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+ RelocInfo::CODE_TARGET);
+}
+
+
+static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) {
+ // Wrap the receiver and patch it back onto the stack.
+ { FrameScope frame_scope(masm, StackFrame::INTERNAL);
+ __ Push(a1, a3);
+ __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
+ __ pop(a1);
+ }
+ __ Branch(USE_DELAY_SLOT, cont);
+ __ sw(v0, MemOperand(sp, argc * kPointerSize));
+}
+
+
void CallFunctionStub::Generate(MacroAssembler* masm) {
// a1 : the function to call
- // a2 : feedback vector
- // a3 : (only if a2 is not the megamorphic symbol) slot in feedback
- // vector (Smi)
Label slow, non_function, wrap, cont;
if (NeedsChecks()) {
@@ -3150,34 +3082,20 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// Goto slow case if we do not have a function.
__ GetObjectType(a1, t0, t0);
__ Branch(&slow, ne, t0, Operand(JS_FUNCTION_TYPE));
-
- if (RecordCallTarget()) {
- GenerateRecordCallTarget(masm);
- // Type information was updated. Because we may call Array, which
- // expects either undefined or an AllocationSite in a2 we need
- // to set a2 to undefined.
- __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
- }
}
// Fast-case: Invoke the function now.
// a1: pushed function
- ParameterCount actual(argc_);
+ int argc = argc_;
+ ParameterCount actual(argc);
if (CallAsMethod()) {
if (NeedsChecks()) {
- // Do not transform the receiver for strict mode functions and natives.
- __ lw(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
- __ lw(t0, FieldMemOperand(a3, SharedFunctionInfo::kCompilerHintsOffset));
- int32_t strict_mode_function_mask =
- 1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize);
- int32_t native_mask = 1 << (SharedFunctionInfo::kNative + kSmiTagSize);
- __ And(at, t0, Operand(strict_mode_function_mask | native_mask));
- __ Branch(&cont, ne, at, Operand(zero_reg));
+ EmitContinueIfStrictOrNative(masm, &cont);
}
// Compute the receiver in sloppy mode.
- __ lw(a3, MemOperand(sp, argc_ * kPointerSize));
+ __ lw(a3, MemOperand(sp, argc * kPointerSize));
if (NeedsChecks()) {
__ JumpIfSmi(a3, &wrap);
@@ -3189,56 +3107,19 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
__ bind(&cont);
}
+
__ InvokeFunction(a1, actual, JUMP_FUNCTION, NullCallWrapper());
if (NeedsChecks()) {
// Slow-case: Non-function called.
__ bind(&slow);
- if (RecordCallTarget()) {
- // If there is a call target cache, mark it megamorphic in the
- // non-function case. MegamorphicSentinel is an immortal immovable
- // object (megamorphic symbol) so no write barrier is needed.
- ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
- masm->isolate()->heap()->megamorphic_symbol());
- __ sll(t1, a3, kPointerSizeLog2 - kSmiTagSize);
- __ Addu(t1, a2, Operand(t1));
- __ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex);
- __ sw(at, FieldMemOperand(t1, FixedArray::kHeaderSize));
- }
- // Check for function proxy.
- __ Branch(&non_function, ne, t0, Operand(JS_FUNCTION_PROXY_TYPE));
- __ push(a1); // Put proxy as additional argument.
- __ li(a0, Operand(argc_ + 1, RelocInfo::NONE32));
- __ li(a2, Operand(0, RelocInfo::NONE32));
- __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY);
- {
- Handle<Code> adaptor =
- masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
- __ Jump(adaptor, RelocInfo::CODE_TARGET);
- }
-
- // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
- // of the original receiver from the call site).
- __ bind(&non_function);
- __ sw(a1, MemOperand(sp, argc_ * kPointerSize));
- __ li(a0, Operand(argc_)); // Set up the number of arguments.
- __ li(a2, Operand(0, RelocInfo::NONE32));
- __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION);
- __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
- RelocInfo::CODE_TARGET);
+ EmitSlowCase(masm, argc, &non_function);
}
if (CallAsMethod()) {
__ bind(&wrap);
// Wrap the receiver and patch it back onto the stack.
- { FrameScope frame_scope(masm, StackFrame::INTERNAL);
- __ Push(a1, a3);
- __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
- __ pop(a1);
- }
- __ mov(a0, v0);
- __ sw(a0, MemOperand(sp, argc_ * kPointerSize));
- __ jmp(&cont);
+ EmitWrapCase(masm, argc, &cont);
}
}
@@ -3302,11 +3183,115 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
__ bind(&do_call);
// Set expected number of arguments to zero (not changing r0).
__ li(a2, Operand(0, RelocInfo::NONE32));
- __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+ __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET);
}
+static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
+ __ lw(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+ __ lw(vector, FieldMemOperand(vector,
+ JSFunction::kSharedFunctionInfoOffset));
+ __ lw(vector, FieldMemOperand(vector,
+ SharedFunctionInfo::kFeedbackVectorOffset));
+}
+
+
+void CallICStub::Generate(MacroAssembler* masm) {
+ // r1 - function
+ // r3 - slot id (Smi)
+ Label extra_checks_or_miss, slow_start;
+ Label slow, non_function, wrap, cont;
+ Label have_js_function;
+ int argc = state_.arg_count();
+ ParameterCount actual(argc);
+
+ EmitLoadTypeFeedbackVector(masm, a2);
+
+ // The checks. First, does r1 match the recorded monomorphic target?
+ __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
+ __ Addu(t0, a2, Operand(t0));
+ __ lw(t0, FieldMemOperand(t0, FixedArray::kHeaderSize));
+ __ Branch(&extra_checks_or_miss, ne, a1, Operand(t0));
+
+ __ bind(&have_js_function);
+ if (state_.CallAsMethod()) {
+ EmitContinueIfStrictOrNative(masm, &cont);
+ // Compute the receiver in sloppy mode.
+ __ lw(a3, MemOperand(sp, argc * kPointerSize));
+
+ __ JumpIfSmi(a3, &wrap);
+ __ GetObjectType(a3, t0, t0);
+ __ Branch(&wrap, lt, t0, Operand(FIRST_SPEC_OBJECT_TYPE));
+
+ __ bind(&cont);
+ }
+
+ __ InvokeFunction(a1, actual, JUMP_FUNCTION, NullCallWrapper());
+
+ __ bind(&slow);
+ EmitSlowCase(masm, argc, &non_function);
+
+ if (state_.CallAsMethod()) {
+ __ bind(&wrap);
+ EmitWrapCase(masm, argc, &cont);
+ }
+
+ __ bind(&extra_checks_or_miss);
+ Label miss;
+
+ __ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex);
+ __ Branch(&slow_start, eq, t0, Operand(at));
+ __ LoadRoot(at, Heap::kUninitializedSymbolRootIndex);
+ __ Branch(&miss, eq, t0, Operand(at));
+
+ if (!FLAG_trace_ic) {
+ // We are going megamorphic, and we don't want to visit the runtime.
+ __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
+ __ Addu(t0, a2, Operand(t0));
+ __ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex);
+ __ sw(at, FieldMemOperand(t0, FixedArray::kHeaderSize));
+ __ Branch(&slow_start);
+ }
+
+ // We are here because tracing is on or we are going monomorphic.
+ __ bind(&miss);
+ GenerateMiss(masm);
+
+ // the slow case
+ __ bind(&slow_start);
+ // Check that the function is really a JavaScript function.
+ // r1: pushed function (to be verified)
+ __ JumpIfSmi(a1, &non_function);
+
+ // Goto slow case if we do not have a function.
+ __ GetObjectType(a1, t0, t0);
+ __ Branch(&slow, ne, t0, Operand(JS_FUNCTION_TYPE));
+ __ Branch(&have_js_function);
+}
+
+
+void CallICStub::GenerateMiss(MacroAssembler* masm) {
+ // Get the receiver of the function from the stack; 1 ~ return address.
+ __ lw(t0, MemOperand(sp, (state_.arg_count() + 1) * kPointerSize));
+
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+
+ // Push the receiver and the function and feedback info.
+ __ Push(t0, a1, a2, a3);
+
+ // Call the entry.
+ ExternalReference miss = ExternalReference(IC_Utility(IC::kCallIC_Miss),
+ masm->isolate());
+ __ CallExternalReference(miss, 4);
+
+ // Move result to a1 and exit the internal frame.
+ __ mov(a1, v0);
+ }
+}
+
+
// StringCharCodeAtGenerator.
void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
Label flat_string;
@@ -3532,9 +3517,15 @@ void StringHelper::GenerateCopyCharactersLong(MacroAssembler* masm,
{
Label loop;
__ bind(&loop);
- __ lwr(scratch1, MemOperand(src));
- __ Addu(src, src, Operand(kReadAlignment));
- __ lwl(scratch1, MemOperand(src, -1));
+ if (kArchEndian == kBig) {
+ __ lwl(scratch1, MemOperand(src));
+ __ Addu(src, src, Operand(kReadAlignment));
+ __ lwr(scratch1, MemOperand(src, -1));
+ } else {
+ __ lwr(scratch1, MemOperand(src));
+ __ Addu(src, src, Operand(kReadAlignment));
+ __ lwl(scratch1, MemOperand(src, -1));
+ }
__ sw(scratch1, MemOperand(dest));
__ Addu(dest, dest, Operand(kReadAlignment));
__ Subu(scratch2, limit, dest);
@@ -3824,7 +3815,7 @@ void SubStringStub::Generate(MacroAssembler* masm) {
masm, a1, t1, a2, a3, t0, t2, t3, t4, DEST_ALWAYS_ALIGNED);
__ bind(&return_v0);
- Counters* counters = masm->isolate()->counters();
+ Counters* counters = isolate()->counters();
__ IncrementCounter(counters->sub_string_native(), 1, a3, t0);
__ DropAndRet(3);
@@ -3968,7 +3959,7 @@ void StringCompareStub::GenerateAsciiCharsCompareLoop(
void StringCompareStub::Generate(MacroAssembler* masm) {
Label runtime;
- Counters* counters = masm->isolate()->counters();
+ Counters* counters = isolate()->counters();
// Stack frame on entry.
// sp[0]: right string
@@ -3999,218 +3990,17 @@ void StringCompareStub::Generate(MacroAssembler* masm) {
}
-void ArrayPushStub::Generate(MacroAssembler* masm) {
- Register receiver = a0;
- Register scratch = a1;
-
- int argc = arguments_count();
-
- if (argc == 0) {
- // Nothing to do, just return the length.
- __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ DropAndRet(argc + 1);
- return;
- }
-
- Isolate* isolate = masm->isolate();
-
- if (argc != 1) {
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- Label call_builtin, attempt_to_grow_elements, with_write_barrier;
-
- Register elements = t2;
- Register end_elements = t1;
- // Get the elements array of the object.
- __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- // Check that the elements are in fast mode and writable.
- __ CheckMap(elements,
- scratch,
- Heap::kFixedArrayMapRootIndex,
- &call_builtin,
- DONT_DO_SMI_CHECK);
- }
-
- // Get the array's length into scratch and calculate new length.
- __ lw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ Addu(scratch, scratch, Operand(Smi::FromInt(argc)));
-
- // Get the elements' length.
- __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
-
- const int kEndElementsOffset =
- FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize;
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- // Check if we could survive without allocation.
- __ Branch(&attempt_to_grow_elements, gt, scratch, Operand(t0));
-
- // Check if value is a smi.
- __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize));
- __ JumpIfNotSmi(t0, &with_write_barrier);
-
- // Store the value.
- // We may need a register containing the address end_elements below,
- // so write back the value in end_elements.
- __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize);
- __ Addu(end_elements, elements, end_elements);
- __ Addu(end_elements, end_elements, kEndElementsOffset);
- __ sw(t0, MemOperand(end_elements));
- } else {
- // Check if we could survive without allocation.
- __ Branch(&call_builtin, gt, scratch, Operand(t0));
-
- __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize));
- __ StoreNumberToDoubleElements(t0, scratch, elements, a3, t1, a2,
- &call_builtin, argc * kDoubleSize);
- }
-
- // Save new length.
- __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ mov(v0, scratch);
- __ DropAndRet(argc + 1);
-
- if (IsFastDoubleElementsKind(elements_kind())) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ bind(&with_write_barrier);
-
- if (IsFastSmiElementsKind(elements_kind())) {
- if (FLAG_trace_elements_transitions) __ jmp(&call_builtin);
-
- __ lw(t3, FieldMemOperand(t0, HeapObject::kMapOffset));
- __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
- __ Branch(&call_builtin, eq, t3, Operand(at));
-
- ElementsKind target_kind = IsHoleyElementsKind(elements_kind())
- ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
- __ lw(a3, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
- __ lw(a3, FieldMemOperand(a3, GlobalObject::kNativeContextOffset));
- __ lw(a3, ContextOperand(a3, Context::JS_ARRAY_MAPS_INDEX));
- const int header_size = FixedArrayBase::kHeaderSize;
- // Verify that the object can be transitioned in place.
- const int origin_offset = header_size + elements_kind() * kPointerSize;
- __ lw(a2, FieldMemOperand(receiver, origin_offset));
- __ lw(at, FieldMemOperand(a3, HeapObject::kMapOffset));
- __ Branch(&call_builtin, ne, a2, Operand(at));
-
-
- const int target_offset = header_size + target_kind * kPointerSize;
- __ lw(a3, FieldMemOperand(a3, target_offset));
- __ mov(a2, receiver);
- ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
- masm, DONT_TRACK_ALLOCATION_SITE, NULL);
- }
-
- // Save new length.
- __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
-
- // Store the value.
- // We may need a register containing the address end_elements below, so write
- // back the value in end_elements.
- __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize);
- __ Addu(end_elements, elements, end_elements);
- __ Addu(end_elements, end_elements, kEndElementsOffset);
- __ sw(t0, MemOperand(end_elements));
-
- __ RecordWrite(elements,
- end_elements,
- t0,
- kRAHasNotBeenSaved,
- kDontSaveFPRegs,
- EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
- __ mov(v0, scratch);
- __ DropAndRet(argc + 1);
-
- __ bind(&attempt_to_grow_elements);
- // scratch: array's length + 1.
-
- if (!FLAG_inline_new) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ lw(a2, MemOperand(sp, (argc - 1) * kPointerSize));
- // Growing elements that are SMI-only requires special handling in case the
- // new element is non-Smi. For now, delegate to the builtin.
- if (IsFastSmiElementsKind(elements_kind())) {
- __ JumpIfNotSmi(a2, &call_builtin);
- }
-
- // We could be lucky and the elements array could be at the top of new-space.
- // In this case we can just grow it in place by moving the allocation pointer
- // up.
- ExternalReference new_space_allocation_top =
- ExternalReference::new_space_allocation_top_address(isolate);
- ExternalReference new_space_allocation_limit =
- ExternalReference::new_space_allocation_limit_address(isolate);
-
- const int kAllocationDelta = 4;
- ASSERT(kAllocationDelta >= argc);
- // Load top and check if it is the end of elements.
- __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize);
- __ Addu(end_elements, elements, end_elements);
- __ Addu(end_elements, end_elements, Operand(kEndElementsOffset));
- __ li(t0, Operand(new_space_allocation_top));
- __ lw(a3, MemOperand(t0));
- __ Branch(&call_builtin, ne, a3, Operand(end_elements));
-
- __ li(t3, Operand(new_space_allocation_limit));
- __ lw(t3, MemOperand(t3));
- __ Addu(a3, a3, Operand(kAllocationDelta * kPointerSize));
- __ Branch(&call_builtin, hi, a3, Operand(t3));
-
- // We fit and could grow elements.
- // Update new_space_allocation_top.
- __ sw(a3, MemOperand(t0));
- // Push the argument.
- __ sw(a2, MemOperand(end_elements));
- // Fill the rest with holes.
- __ LoadRoot(a3, Heap::kTheHoleValueRootIndex);
- for (int i = 1; i < kAllocationDelta; i++) {
- __ sw(a3, MemOperand(end_elements, i * kPointerSize));
- }
-
- // Update elements' and array's sizes.
- __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
- __ Addu(t0, t0, Operand(Smi::FromInt(kAllocationDelta)));
- __ sw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
-
- // Elements are in new space, so write barrier is not required.
- __ mov(v0, scratch);
- __ DropAndRet(argc + 1);
-
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
-}
-
-
void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a1 : left
// -- a0 : right
// -- ra : return address
// -----------------------------------
- Isolate* isolate = masm->isolate();
// Load a2 with the allocation site. We stick an undefined dummy value here
// and replace it with the real allocation site later when we instantiate this
// stub in BinaryOpICWithAllocationSiteStub::GetCodeCopyFromTemplate().
- __ li(a2, handle(isolate->heap()->undefined_value()));
+ __ li(a2, handle(isolate()->heap()->undefined_value()));
// Make sure that we actually patched the allocation site.
if (FLAG_debug_code) {
@@ -4223,7 +4013,7 @@ void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
// Tail call into the stub that handles binary operations with allocation
// sites.
- BinaryOpWithAllocationSiteStub stub(state_);
+ BinaryOpWithAllocationSiteStub stub(isolate(), state_);
__ TailCallStub(&stub);
}
@@ -4319,9 +4109,9 @@ void ICCompareStub::GenerateNumbers(MacroAssembler* masm) {
__ bind(&unordered);
__ bind(&generic_stub);
- ICCompareStub stub(op_, CompareIC::GENERIC, CompareIC::GENERIC,
+ ICCompareStub stub(isolate(), op_, CompareIC::GENERIC, CompareIC::GENERIC,
CompareIC::GENERIC);
- __ Jump(stub.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
+ __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
__ bind(&maybe_undefined1);
if (Token::IsOrderedRelationalCompareOp(op_)) {
@@ -4555,7 +4345,7 @@ void ICCompareStub::GenerateMiss(MacroAssembler* masm) {
{
// Call the runtime system in a fresh internal frame.
ExternalReference miss =
- ExternalReference(IC_Utility(IC::kCompareIC_Miss), masm->isolate());
+ ExternalReference(IC_Utility(IC::kCompareIC_Miss), isolate());
FrameScope scope(masm, StackFrame::INTERNAL);
__ Push(a1, a0);
__ Push(ra, a1, a0);
@@ -4600,7 +4390,7 @@ void DirectCEntryStub::Generate(MacroAssembler* masm) {
void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
Register target) {
intptr_t loc =
- reinterpret_cast<intptr_t>(GetCode(masm->isolate()).location());
+ reinterpret_cast<intptr_t>(GetCode().location());
__ Move(t9, target);
__ li(ra, Operand(loc, RelocInfo::CODE_TARGET), CONSTANT_SIZE);
__ Call(ra);
@@ -4675,7 +4465,7 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
__ MultiPush(spill_mask);
__ lw(a0, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
__ li(a1, Operand(Handle<Name>(name)));
- NameDictionaryLookupStub stub(NEGATIVE_LOOKUP);
+ NameDictionaryLookupStub stub(masm->isolate(), NEGATIVE_LOOKUP);
__ CallStub(&stub);
__ mov(at, v0);
__ MultiPop(spill_mask);
@@ -4754,7 +4544,7 @@ void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
__ Move(a0, elements);
__ Move(a1, name);
}
- NameDictionaryLookupStub stub(POSITIVE_LOOKUP);
+ NameDictionaryLookupStub stub(masm->isolate(), POSITIVE_LOOKUP);
__ CallStub(&stub);
__ mov(scratch2, a2);
__ mov(at, v0);
@@ -4862,11 +4652,11 @@ void NameDictionaryLookupStub::Generate(MacroAssembler* masm) {
void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
Isolate* isolate) {
- StoreBufferOverflowStub stub1(kDontSaveFPRegs);
- stub1.GetCode(isolate);
+ StoreBufferOverflowStub stub1(isolate, kDontSaveFPRegs);
+ stub1.GetCode();
// Hydrogen code stubs need stub2 at snapshot time.
- StoreBufferOverflowStub stub2(kSaveFPRegs);
- stub2.GetCode(isolate);
+ StoreBufferOverflowStub stub2(isolate, kSaveFPRegs);
+ stub2.GetCode();
}
@@ -4968,12 +4758,11 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
__ Move(address, regs_.address());
__ Move(a0, regs_.object());
__ Move(a1, address);
- __ li(a2, Operand(ExternalReference::isolate_address(masm->isolate())));
+ __ li(a2, Operand(ExternalReference::isolate_address(isolate())));
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(
- ExternalReference::incremental_marking_record_write_function(
- masm->isolate()),
+ ExternalReference::incremental_marking_record_write_function(isolate()),
argument_count);
regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode_);
}
@@ -5133,8 +4922,8 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
- CEntryStub ces(1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
- __ Call(ces.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
+ CEntryStub ces(isolate(), 1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
+ __ Call(ces.GetCode(), RelocInfo::CODE_TARGET);
int parameter_count_offset =
StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
__ lw(a1, MemOperand(fp, parameter_count_offset));
@@ -5150,7 +4939,7 @@ void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
if (masm->isolate()->function_entry_hook() != NULL) {
- ProfileEntryHookStub stub;
+ ProfileEntryHookStub stub(masm->isolate());
__ push(ra);
__ CallStub(&stub);
__ pop(ra);
@@ -5192,18 +4981,18 @@ void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
__ Subu(sp, sp, kCArgsSlotsSize);
#if defined(V8_HOST_ARCH_MIPS)
int32_t entry_hook =
- reinterpret_cast<int32_t>(masm->isolate()->function_entry_hook());
+ reinterpret_cast<int32_t>(isolate()->function_entry_hook());
__ li(t9, Operand(entry_hook));
#else
// Under the simulator we need to indirect the entry hook through a
// trampoline function at a known address.
// It additionally takes an isolate as a third parameter.
- __ li(a2, Operand(ExternalReference::isolate_address(masm->isolate())));
+ __ li(a2, Operand(ExternalReference::isolate_address(isolate())));
ApiFunction dispatcher(FUNCTION_ADDR(EntryHookTrampoline));
__ li(t9, Operand(ExternalReference(&dispatcher,
ExternalReference::BUILTIN_CALL,
- masm->isolate())));
+ isolate())));
#endif
// Call C function through t9 to conform ABI for PIC.
__ Call(t9);
@@ -5225,14 +5014,14 @@ template<class T>
static void CreateArrayDispatch(MacroAssembler* masm,
AllocationSiteOverrideMode mode) {
if (mode == DISABLE_ALLOCATION_SITES) {
- T stub(GetInitialFastElementsKind(), mode);
+ T stub(masm->isolate(), GetInitialFastElementsKind(), mode);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
int last_index = GetSequenceIndexFromFastElementsKind(
TERMINAL_FAST_ELEMENTS_KIND);
for (int i = 0; i <= last_index; ++i) {
ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
- T stub(kind);
+ T stub(masm->isolate(), kind);
__ TailCallStub(&stub, eq, a3, Operand(kind));
}
@@ -5273,12 +5062,14 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
ElementsKind initial = GetInitialFastElementsKind();
ElementsKind holey_initial = GetHoleyElementsKind(initial);
- ArraySingleArgumentConstructorStub stub_holey(holey_initial,
+ ArraySingleArgumentConstructorStub stub_holey(masm->isolate(),
+ holey_initial,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub_holey);
__ bind(&normal_sequence);
- ArraySingleArgumentConstructorStub stub(initial,
+ ArraySingleArgumentConstructorStub stub(masm->isolate(),
+ initial,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
@@ -5306,7 +5097,7 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
TERMINAL_FAST_ELEMENTS_KIND);
for (int i = 0; i <= last_index; ++i) {
ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
- ArraySingleArgumentConstructorStub stub(kind);
+ ArraySingleArgumentConstructorStub stub(masm->isolate(), kind);
__ TailCallStub(&stub, eq, a3, Operand(kind));
}
@@ -5324,11 +5115,11 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
TERMINAL_FAST_ELEMENTS_KIND);
for (int i = 0; i <= to_index; ++i) {
ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
- T stub(kind);
- stub.GetCode(isolate);
+ T stub(isolate, kind);
+ stub.GetCode();
if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
- T stub1(kind, DISABLE_ALLOCATION_SITES);
- stub1.GetCode(isolate);
+ T stub1(isolate, kind, DISABLE_ALLOCATION_SITES);
+ stub1.GetCode();
}
}
}
@@ -5349,12 +5140,12 @@ void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
for (int i = 0; i < 2; i++) {
// For internal arrays we only need a few things.
- InternalArrayNoArgumentConstructorStub stubh1(kinds[i]);
- stubh1.GetCode(isolate);
- InternalArraySingleArgumentConstructorStub stubh2(kinds[i]);
- stubh2.GetCode(isolate);
- InternalArrayNArgumentsConstructorStub stubh3(kinds[i]);
- stubh3.GetCode(isolate);
+ InternalArrayNoArgumentConstructorStub stubh1(isolate, kinds[i]);
+ stubh1.GetCode();
+ InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]);
+ stubh2.GetCode();
+ InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]);
+ stubh3.GetCode();
}
}
@@ -5432,10 +5223,10 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
void InternalArrayConstructorStub::GenerateCase(
MacroAssembler* masm, ElementsKind kind) {
- InternalArrayNoArgumentConstructorStub stub0(kind);
+ InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
__ TailCallStub(&stub0, lo, a0, Operand(1));
- InternalArrayNArgumentsConstructorStub stubN(kind);
+ InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
__ TailCallStub(&stubN, hi, a0, Operand(1));
if (IsFastPackedElementsKind(kind)) {
@@ -5444,11 +5235,11 @@ void InternalArrayConstructorStub::GenerateCase(
__ lw(at, MemOperand(sp, 0));
InternalArraySingleArgumentConstructorStub
- stub1_holey(GetHoleyElementsKind(kind));
+ stub1_holey(isolate(), GetHoleyElementsKind(kind));
__ TailCallStub(&stub1_holey, ne, at, Operand(zero_reg));
}
- InternalArraySingleArgumentConstructorStub stub1(kind);
+ InternalArraySingleArgumentConstructorStub stub1(isolate(), kind);
__ TailCallStub(&stub1);
}
@@ -5538,8 +5329,6 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(FCA::kHolderIndex == 0);
STATIC_ASSERT(FCA::kArgsLength == 7);
- Isolate* isolate = masm->isolate();
-
// Save context, callee and call data.
__ Push(context, callee, call_data);
// Load context from callee.
@@ -5552,7 +5341,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
// Push return value and default return value.
__ Push(scratch, scratch);
__ li(scratch,
- Operand(ExternalReference::isolate_address(isolate)));
+ Operand(ExternalReference::isolate_address(isolate())));
// Push isolate and holder.
__ Push(scratch, holder);
@@ -5582,11 +5371,8 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
__ sw(zero_reg, MemOperand(a0, 3 * kPointerSize));
const int kStackUnwindSpace = argc + FCA::kArgsLength + 1;
- Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
- ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
- ApiFunction thunk_fun(thunk_address);
- ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
- masm->isolate());
+ ExternalReference thunk_ref =
+ ExternalReference::invoke_function_callback(isolate());
AllowExternalCallThatCantCauseGC scope(masm);
MemOperand context_restore_operand(
@@ -5632,12 +5418,8 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
- Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
- ExternalReference::Type thunk_type =
- ExternalReference::PROFILING_GETTER_CALL;
- ApiFunction thunk_fun(thunk_address);
- ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
- masm->isolate());
+ ExternalReference thunk_ref =
+ ExternalReference::invoke_accessor_getter_callback(isolate());
__ CallApiFunctionAndReturn(api_function_address,
thunk_ref,
kStackUnwindSpace,
diff --git a/deps/v8/src/mips/code-stubs-mips.h b/deps/v8/src/mips/code-stubs-mips.h
index e71c30583e..64577f903d 100644
--- a/deps/v8/src/mips/code-stubs-mips.h
+++ b/deps/v8/src/mips/code-stubs-mips.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_MIPS_CODE_STUBS_ARM_H_
#define V8_MIPS_CODE_STUBS_ARM_H_
@@ -40,8 +17,8 @@ void ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code);
class StoreBufferOverflowStub: public PlatformCodeStub {
public:
- explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp)
- : save_doubles_(save_fp) {}
+ StoreBufferOverflowStub(Isolate* isolate, SaveFPRegsMode save_fp)
+ : PlatformCodeStub(isolate), save_doubles_(save_fp) {}
void Generate(MacroAssembler* masm);
@@ -93,7 +70,7 @@ class StringHelper : public AllStatic {
class SubStringStub: public PlatformCodeStub {
public:
- SubStringStub() {}
+ explicit SubStringStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
private:
Major MajorKey() { return SubString; }
@@ -104,8 +81,8 @@ class SubStringStub: public PlatformCodeStub {
class StoreRegistersStateStub: public PlatformCodeStub {
public:
- explicit StoreRegistersStateStub(SaveFPRegsMode with_fp)
- : save_doubles_(with_fp) {}
+ explicit StoreRegistersStateStub(Isolate* isolate, SaveFPRegsMode with_fp)
+ : PlatformCodeStub(isolate), save_doubles_(with_fp) {}
static void GenerateAheadOfTime(Isolate* isolate);
private:
@@ -118,8 +95,8 @@ class StoreRegistersStateStub: public PlatformCodeStub {
class RestoreRegistersStateStub: public PlatformCodeStub {
public:
- explicit RestoreRegistersStateStub(SaveFPRegsMode with_fp)
- : save_doubles_(with_fp) {}
+ explicit RestoreRegistersStateStub(Isolate* isolate, SaveFPRegsMode with_fp)
+ : PlatformCodeStub(isolate), save_doubles_(with_fp) {}
static void GenerateAheadOfTime(Isolate* isolate);
private:
@@ -132,7 +109,7 @@ class RestoreRegistersStateStub: public PlatformCodeStub {
class StringCompareStub: public PlatformCodeStub {
public:
- StringCompareStub() { }
+ explicit StringCompareStub(Isolate* isolate) : PlatformCodeStub(isolate) { }
// Compare two flat ASCII strings and returns result in v0.
static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
@@ -173,11 +150,13 @@ class StringCompareStub: public PlatformCodeStub {
// so you don't have to set up the frame.
class WriteInt32ToHeapNumberStub : public PlatformCodeStub {
public:
- WriteInt32ToHeapNumberStub(Register the_int,
+ WriteInt32ToHeapNumberStub(Isolate* isolate,
+ Register the_int,
Register the_heap_number,
Register scratch,
Register scratch2)
- : the_int_(the_int),
+ : PlatformCodeStub(isolate),
+ the_int_(the_int),
the_heap_number_(the_heap_number),
scratch_(scratch),
sign_(scratch2) {
@@ -216,12 +195,14 @@ class WriteInt32ToHeapNumberStub : public PlatformCodeStub {
class RecordWriteStub: public PlatformCodeStub {
public:
- RecordWriteStub(Register object,
+ RecordWriteStub(Isolate* isolate,
+ Register object,
Register value,
Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode)
- : object_(object),
+ : PlatformCodeStub(isolate),
+ object_(object),
value_(value),
address_(address),
remembered_set_action_(remembered_set_action),
@@ -406,7 +387,7 @@ class RecordWriteStub: public PlatformCodeStub {
// moved by GC
class DirectCEntryStub: public PlatformCodeStub {
public:
- DirectCEntryStub() {}
+ explicit DirectCEntryStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
void Generate(MacroAssembler* masm);
void GenerateCall(MacroAssembler* masm, Register target);
@@ -422,7 +403,8 @@ class NameDictionaryLookupStub: public PlatformCodeStub {
public:
enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
- explicit NameDictionaryLookupStub(LookupMode mode) : mode_(mode) { }
+ NameDictionaryLookupStub(Isolate* isolate, LookupMode mode)
+ : PlatformCodeStub(isolate), mode_(mode) { }
void Generate(MacroAssembler* masm);
diff --git a/deps/v8/src/mips/codegen-mips.cc b/deps/v8/src/mips/codegen-mips.cc
index 1b79433d37..adf6d37d89 100644
--- a/deps/v8/src/mips/codegen-mips.cc
+++ b/deps/v8/src/mips/codegen-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -67,21 +44,13 @@ UnaryMathFunction CreateExpFunction() {
Register temp2 = t1;
Register temp3 = t2;
- if (!IsMipsSoftFloatABI) {
- // Input value is in f12 anyway, nothing to do.
- } else {
- __ Move(input, a0, a1);
- }
+ __ MovFromFloatParameter(input);
__ Push(temp3, temp2, temp1);
MathExpGenerator::EmitMathExp(
&masm, input, result, double_scratch1, double_scratch2,
temp1, temp2, temp3);
__ Pop(temp3, temp2, temp1);
- if (!IsMipsSoftFloatABI) {
- // Result is already in f0, nothing to do.
- } else {
- __ Move(v0, v1, result);
- }
+ __ MovToFloatResult(result);
__ Ret();
}
@@ -103,14 +72,10 @@ UnaryMathFunction CreateExpFunction() {
#if defined(V8_HOST_ARCH_MIPS)
OS::MemCopyUint8Function CreateMemCopyUint8Function(
- OS::MemCopyUint8Function stub) {
+ OS::MemCopyUint8Function stub) {
#if defined(USE_SIMULATOR)
return stub;
#else
- if (Serializer::enabled()) {
- return stub;
- }
-
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(3 * KB, &actual_size, true));
if (buffer == NULL) return stub;
@@ -167,11 +132,17 @@ OS::MemCopyUint8Function CreateMemCopyUint8Function(
__ beq(a3, zero_reg, &aligned); // Already aligned.
__ subu(a2, a2, a3); // In delay slot. a2 is the remining bytes count.
- __ lwr(t8, MemOperand(a1));
- __ addu(a1, a1, a3);
- __ swr(t8, MemOperand(a0));
- __ addu(a0, a0, a3);
-
+ if (kArchEndian == kLittle) {
+ __ lwr(t8, MemOperand(a1));
+ __ addu(a1, a1, a3);
+ __ swr(t8, MemOperand(a0));
+ __ addu(a0, a0, a3);
+ } else {
+ __ lwl(t8, MemOperand(a1));
+ __ addu(a1, a1, a3);
+ __ swl(t8, MemOperand(a0));
+ __ addu(a0, a0, a3);
+ }
// Now dst/src are both aligned to (word) aligned addresses. Set a2 to
// count how many bytes we have to copy after all the 64 byte chunks are
// copied and a3 to the dst pointer after all the 64 byte chunks have been
@@ -323,12 +294,21 @@ OS::MemCopyUint8Function CreateMemCopyUint8Function(
__ beq(a3, zero_reg, &ua_chk16w);
__ subu(a2, a2, a3); // In delay slot.
- __ lwr(v1, MemOperand(a1));
- __ lwl(v1,
- MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
- __ addu(a1, a1, a3);
- __ swr(v1, MemOperand(a0));
- __ addu(a0, a0, a3);
+ if (kArchEndian == kLittle) {
+ __ lwr(v1, MemOperand(a1));
+ __ lwl(v1,
+ MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
+ __ addu(a1, a1, a3);
+ __ swr(v1, MemOperand(a0));
+ __ addu(a0, a0, a3);
+ } else {
+ __ lwl(v1, MemOperand(a1));
+ __ lwr(v1,
+ MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
+ __ addu(a1, a1, a3);
+ __ swl(v1, MemOperand(a0));
+ __ addu(a0, a0, a3);
+ }
// Now the dst (but not the source) is aligned. Set a2 to count how many
// bytes we have to copy after all the 64 byte chunks are copied and a3 to
@@ -357,40 +337,77 @@ OS::MemCopyUint8Function CreateMemCopyUint8Function(
__ bind(&ua_loop16w);
__ Pref(pref_hint_load, MemOperand(a1, 3 * pref_chunk));
- __ lwr(t0, MemOperand(a1));
- __ lwr(t1, MemOperand(a1, 1, loadstore_chunk));
- __ lwr(t2, MemOperand(a1, 2, loadstore_chunk));
-
- if (pref_hint_store == kPrefHintPrepareForStore) {
- __ sltu(v1, t9, a0);
- __ Branch(USE_DELAY_SLOT, &ua_skip_pref, gt, v1, Operand(zero_reg));
+ if (kArchEndian == kLittle) {
+ __ lwr(t0, MemOperand(a1));
+ __ lwr(t1, MemOperand(a1, 1, loadstore_chunk));
+ __ lwr(t2, MemOperand(a1, 2, loadstore_chunk));
+
+ if (pref_hint_store == kPrefHintPrepareForStore) {
+ __ sltu(v1, t9, a0);
+ __ Branch(USE_DELAY_SLOT, &ua_skip_pref, gt, v1, Operand(zero_reg));
+ }
+ __ lwr(t3, MemOperand(a1, 3, loadstore_chunk)); // Maybe in delay slot.
+
+ __ Pref(pref_hint_store, MemOperand(a0, 4 * pref_chunk));
+ __ Pref(pref_hint_store, MemOperand(a0, 5 * pref_chunk));
+
+ __ bind(&ua_skip_pref);
+ __ lwr(t4, MemOperand(a1, 4, loadstore_chunk));
+ __ lwr(t5, MemOperand(a1, 5, loadstore_chunk));
+ __ lwr(t6, MemOperand(a1, 6, loadstore_chunk));
+ __ lwr(t7, MemOperand(a1, 7, loadstore_chunk));
+ __ lwl(t0,
+ MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t1,
+ MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t2,
+ MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t3,
+ MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t4,
+ MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t5,
+ MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t6,
+ MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t7,
+ MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
+ } else {
+ __ lwl(t0, MemOperand(a1));
+ __ lwl(t1, MemOperand(a1, 1, loadstore_chunk));
+ __ lwl(t2, MemOperand(a1, 2, loadstore_chunk));
+
+ if (pref_hint_store == kPrefHintPrepareForStore) {
+ __ sltu(v1, t9, a0);
+ __ Branch(USE_DELAY_SLOT, &ua_skip_pref, gt, v1, Operand(zero_reg));
+ }
+ __ lwl(t3, MemOperand(a1, 3, loadstore_chunk)); // Maybe in delay slot.
+
+ __ Pref(pref_hint_store, MemOperand(a0, 4 * pref_chunk));
+ __ Pref(pref_hint_store, MemOperand(a0, 5 * pref_chunk));
+
+ __ bind(&ua_skip_pref);
+ __ lwl(t4, MemOperand(a1, 4, loadstore_chunk));
+ __ lwl(t5, MemOperand(a1, 5, loadstore_chunk));
+ __ lwl(t6, MemOperand(a1, 6, loadstore_chunk));
+ __ lwl(t7, MemOperand(a1, 7, loadstore_chunk));
+ __ lwr(t0,
+ MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t1,
+ MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t2,
+ MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t3,
+ MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t4,
+ MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t5,
+ MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t6,
+ MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t7,
+ MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
}
- __ lwr(t3, MemOperand(a1, 3, loadstore_chunk)); // Maybe in delay slot.
-
- __ Pref(pref_hint_store, MemOperand(a0, 4 * pref_chunk));
- __ Pref(pref_hint_store, MemOperand(a0, 5 * pref_chunk));
-
- __ bind(&ua_skip_pref);
- __ lwr(t4, MemOperand(a1, 4, loadstore_chunk));
- __ lwr(t5, MemOperand(a1, 5, loadstore_chunk));
- __ lwr(t6, MemOperand(a1, 6, loadstore_chunk));
- __ lwr(t7, MemOperand(a1, 7, loadstore_chunk));
- __ lwl(t0,
- MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t1,
- MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t2,
- MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t3,
- MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t4,
- MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t5,
- MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t6,
- MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t7,
- MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
__ Pref(pref_hint_load, MemOperand(a1, 4 * pref_chunk));
__ sw(t0, MemOperand(a0));
__ sw(t1, MemOperand(a0, 1, loadstore_chunk));
@@ -400,30 +417,57 @@ OS::MemCopyUint8Function CreateMemCopyUint8Function(
__ sw(t5, MemOperand(a0, 5, loadstore_chunk));
__ sw(t6, MemOperand(a0, 6, loadstore_chunk));
__ sw(t7, MemOperand(a0, 7, loadstore_chunk));
- __ lwr(t0, MemOperand(a1, 8, loadstore_chunk));
- __ lwr(t1, MemOperand(a1, 9, loadstore_chunk));
- __ lwr(t2, MemOperand(a1, 10, loadstore_chunk));
- __ lwr(t3, MemOperand(a1, 11, loadstore_chunk));
- __ lwr(t4, MemOperand(a1, 12, loadstore_chunk));
- __ lwr(t5, MemOperand(a1, 13, loadstore_chunk));
- __ lwr(t6, MemOperand(a1, 14, loadstore_chunk));
- __ lwr(t7, MemOperand(a1, 15, loadstore_chunk));
- __ lwl(t0,
- MemOperand(a1, 9, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t1,
- MemOperand(a1, 10, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t2,
- MemOperand(a1, 11, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t3,
- MemOperand(a1, 12, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t4,
- MemOperand(a1, 13, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t5,
- MemOperand(a1, 14, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t6,
- MemOperand(a1, 15, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t7,
- MemOperand(a1, 16, loadstore_chunk, MemOperand::offset_minus_one));
+ if (kArchEndian == kLittle) {
+ __ lwr(t0, MemOperand(a1, 8, loadstore_chunk));
+ __ lwr(t1, MemOperand(a1, 9, loadstore_chunk));
+ __ lwr(t2, MemOperand(a1, 10, loadstore_chunk));
+ __ lwr(t3, MemOperand(a1, 11, loadstore_chunk));
+ __ lwr(t4, MemOperand(a1, 12, loadstore_chunk));
+ __ lwr(t5, MemOperand(a1, 13, loadstore_chunk));
+ __ lwr(t6, MemOperand(a1, 14, loadstore_chunk));
+ __ lwr(t7, MemOperand(a1, 15, loadstore_chunk));
+ __ lwl(t0,
+ MemOperand(a1, 9, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t1,
+ MemOperand(a1, 10, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t2,
+ MemOperand(a1, 11, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t3,
+ MemOperand(a1, 12, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t4,
+ MemOperand(a1, 13, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t5,
+ MemOperand(a1, 14, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t6,
+ MemOperand(a1, 15, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t7,
+ MemOperand(a1, 16, loadstore_chunk, MemOperand::offset_minus_one));
+ } else {
+ __ lwl(t0, MemOperand(a1, 8, loadstore_chunk));
+ __ lwl(t1, MemOperand(a1, 9, loadstore_chunk));
+ __ lwl(t2, MemOperand(a1, 10, loadstore_chunk));
+ __ lwl(t3, MemOperand(a1, 11, loadstore_chunk));
+ __ lwl(t4, MemOperand(a1, 12, loadstore_chunk));
+ __ lwl(t5, MemOperand(a1, 13, loadstore_chunk));
+ __ lwl(t6, MemOperand(a1, 14, loadstore_chunk));
+ __ lwl(t7, MemOperand(a1, 15, loadstore_chunk));
+ __ lwr(t0,
+ MemOperand(a1, 9, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t1,
+ MemOperand(a1, 10, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t2,
+ MemOperand(a1, 11, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t3,
+ MemOperand(a1, 12, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t4,
+ MemOperand(a1, 13, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t5,
+ MemOperand(a1, 14, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t6,
+ MemOperand(a1, 15, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t7,
+ MemOperand(a1, 16, loadstore_chunk, MemOperand::offset_minus_one));
+ }
__ Pref(pref_hint_load, MemOperand(a1, 5 * pref_chunk));
__ sw(t0, MemOperand(a0, 8, loadstore_chunk));
__ sw(t1, MemOperand(a0, 9, loadstore_chunk));
@@ -447,30 +491,57 @@ OS::MemCopyUint8Function CreateMemCopyUint8Function(
__ beq(a2, t8, &ua_chk1w);
__ nop(); // In delay slot.
- __ lwr(t0, MemOperand(a1));
- __ lwr(t1, MemOperand(a1, 1, loadstore_chunk));
- __ lwr(t2, MemOperand(a1, 2, loadstore_chunk));
- __ lwr(t3, MemOperand(a1, 3, loadstore_chunk));
- __ lwr(t4, MemOperand(a1, 4, loadstore_chunk));
- __ lwr(t5, MemOperand(a1, 5, loadstore_chunk));
- __ lwr(t6, MemOperand(a1, 6, loadstore_chunk));
- __ lwr(t7, MemOperand(a1, 7, loadstore_chunk));
- __ lwl(t0,
- MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t1,
- MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t2,
- MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t3,
- MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t4,
- MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t5,
- MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t6,
- MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
- __ lwl(t7,
- MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
+ if (kArchEndian == kLittle) {
+ __ lwr(t0, MemOperand(a1));
+ __ lwr(t1, MemOperand(a1, 1, loadstore_chunk));
+ __ lwr(t2, MemOperand(a1, 2, loadstore_chunk));
+ __ lwr(t3, MemOperand(a1, 3, loadstore_chunk));
+ __ lwr(t4, MemOperand(a1, 4, loadstore_chunk));
+ __ lwr(t5, MemOperand(a1, 5, loadstore_chunk));
+ __ lwr(t6, MemOperand(a1, 6, loadstore_chunk));
+ __ lwr(t7, MemOperand(a1, 7, loadstore_chunk));
+ __ lwl(t0,
+ MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t1,
+ MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t2,
+ MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t3,
+ MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t4,
+ MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t5,
+ MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t6,
+ MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t7,
+ MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
+ } else {
+ __ lwl(t0, MemOperand(a1));
+ __ lwl(t1, MemOperand(a1, 1, loadstore_chunk));
+ __ lwl(t2, MemOperand(a1, 2, loadstore_chunk));
+ __ lwl(t3, MemOperand(a1, 3, loadstore_chunk));
+ __ lwl(t4, MemOperand(a1, 4, loadstore_chunk));
+ __ lwl(t5, MemOperand(a1, 5, loadstore_chunk));
+ __ lwl(t6, MemOperand(a1, 6, loadstore_chunk));
+ __ lwl(t7, MemOperand(a1, 7, loadstore_chunk));
+ __ lwr(t0,
+ MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t1,
+ MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t2,
+ MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t3,
+ MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t4,
+ MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t5,
+ MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t6,
+ MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwr(t7,
+ MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
+ }
__ addiu(a1, a1, 8 * loadstore_chunk);
__ sw(t0, MemOperand(a0));
__ sw(t1, MemOperand(a0, 1, loadstore_chunk));
@@ -491,9 +562,15 @@ OS::MemCopyUint8Function CreateMemCopyUint8Function(
__ addu(a3, a0, a3);
__ bind(&ua_wordCopy_loop);
- __ lwr(v1, MemOperand(a1));
- __ lwl(v1,
- MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
+ if (kArchEndian == kLittle) {
+ __ lwr(v1, MemOperand(a1));
+ __ lwl(v1,
+ MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
+ } else {
+ __ lwl(v1, MemOperand(a1));
+ __ lwr(v1,
+ MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
+ }
__ addiu(a0, a0, loadstore_chunk);
__ addiu(a1, a1, loadstore_chunk);
__ bne(a0, a3, &ua_wordCopy_loop);
@@ -722,8 +799,8 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
__ LoadRoot(at, Heap::kTheHoleValueRootIndex);
__ Assert(eq, kObjectFoundInSmiOnlyArray, at, Operand(t5));
}
- __ sw(t0, MemOperand(t3)); // mantissa
- __ sw(t1, MemOperand(t3, kIntSize)); // exponent
+ __ sw(t0, MemOperand(t3, Register::kMantissaOffset)); // mantissa
+ __ sw(t1, MemOperand(t3, Register::kExponentOffset)); // exponent
__ Addu(t3, t3, kDoubleSize);
__ bind(&entry);
@@ -773,7 +850,9 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
__ sw(t5, MemOperand(t2, HeapObject::kMapOffset));
// Prepare for conversion loop.
- __ Addu(t0, t0, Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag + 4));
+ __ Addu(t0, t0, Operand(
+ FixedDoubleArray::kHeaderSize - kHeapObjectTag
+ + Register::kExponentOffset));
__ Addu(a3, t2, Operand(FixedArray::kHeaderSize));
__ Addu(t2, t2, Operand(kHeapObjectTag));
__ sll(t1, t1, 1);
@@ -782,7 +861,8 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
__ LoadRoot(t5, Heap::kHeapNumberMapRootIndex);
// Using offsetted addresses.
// a3: begin of destination FixedArray element fields, not tagged
- // t0: begin of source FixedDoubleArray element fields, not tagged, +4
+ // t0: begin of source FixedDoubleArray element fields, not tagged,
+ // points to the exponent
// t1: end of destination FixedArray, not tagged
// t2: destination FixedArray
// t3: the-hole pointer
@@ -805,7 +885,9 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
// Non-hole double, copy value into a heap number.
__ AllocateHeapNumber(a2, a0, t6, t5, &gc_required);
// a2: new heap number
- __ lw(a0, MemOperand(t0, -12));
+ // Load mantissa of current element, t0 point to exponent of next element.
+ __ lw(a0, MemOperand(t0, (Register::kMantissaOffset
+ - Register::kExponentOffset - kDoubleSize)));
__ sw(a0, FieldMemOperand(a2, HeapNumber::kMantissaOffset));
__ sw(a1, FieldMemOperand(a2, HeapNumber::kExponentOffset));
__ mov(a0, a3);
@@ -1010,8 +1092,8 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
__ li(temp3, Operand(ExternalReference::math_exp_log_table()));
__ sll(at, temp2, 3);
__ Addu(temp3, temp3, Operand(at));
- __ lw(temp2, MemOperand(temp3, 0));
- __ lw(temp3, MemOperand(temp3, kPointerSize));
+ __ lw(temp2, MemOperand(temp3, Register::kMantissaOffset));
+ __ lw(temp3, MemOperand(temp3, Register::kExponentOffset));
// The first word is loaded is the lower number register.
if (temp2.code() < temp3.code()) {
__ sll(at, temp1, 20);
@@ -1040,42 +1122,42 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
static const uint32_t kCodeAgePatchFirstInstruction = 0x00010180;
#endif
-static byte* GetNoCodeAgeSequence(uint32_t* length) {
- // The sequence of instructions that is patched out for aging code is the
- // following boilerplate stack-building prologue that is found in FUNCTIONS
- static bool initialized = false;
- static uint32_t sequence[kNoCodeAgeSequenceLength];
- byte* byte_sequence = reinterpret_cast<byte*>(sequence);
- *length = kNoCodeAgeSequenceLength * Assembler::kInstrSize;
- if (!initialized) {
- // Since patcher is a large object, allocate it dynamically when needed,
- // to avoid overloading the stack in stress conditions.
- SmartPointer<CodePatcher>
- patcher(new CodePatcher(byte_sequence, kNoCodeAgeSequenceLength));
- PredictableCodeSizeScope scope(patcher->masm(), *length);
- patcher->masm()->Push(ra, fp, cp, a1);
- patcher->masm()->nop(Assembler::CODE_AGE_SEQUENCE_NOP);
- patcher->masm()->Addu(
- fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
- initialized = true;
- }
- return byte_sequence;
+
+CodeAgingHelper::CodeAgingHelper() {
+ ASSERT(young_sequence_.length() == kNoCodeAgeSequenceLength);
+ // Since patcher is a large object, allocate it dynamically when needed,
+ // to avoid overloading the stack in stress conditions.
+ // DONT_FLUSH is used because the CodeAgingHelper is initialized early in
+ // the process, before MIPS simulator ICache is setup.
+ SmartPointer<CodePatcher> patcher(
+ new CodePatcher(young_sequence_.start(),
+ young_sequence_.length() / Assembler::kInstrSize,
+ CodePatcher::DONT_FLUSH));
+ PredictableCodeSizeScope scope(patcher->masm(), young_sequence_.length());
+ patcher->masm()->Push(ra, fp, cp, a1);
+ patcher->masm()->nop(Assembler::CODE_AGE_SEQUENCE_NOP);
+ patcher->masm()->Addu(
+ fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
}
-bool Code::IsYoungSequence(byte* sequence) {
- uint32_t young_length;
- byte* young_sequence = GetNoCodeAgeSequence(&young_length);
- bool result = !memcmp(sequence, young_sequence, young_length);
- ASSERT(result ||
- Memory::uint32_at(sequence) == kCodeAgePatchFirstInstruction);
+#ifdef DEBUG
+bool CodeAgingHelper::IsOld(byte* candidate) const {
+ return Memory::uint32_at(candidate) == kCodeAgePatchFirstInstruction;
+}
+#endif
+
+
+bool Code::IsYoungSequence(Isolate* isolate, byte* sequence) {
+ bool result = isolate->code_aging_helper()->IsYoung(sequence);
+ ASSERT(result || isolate->code_aging_helper()->IsOld(sequence));
return result;
}
-void Code::GetCodeAgeAndParity(byte* sequence, Age* age,
+void Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
MarkingParity* parity) {
- if (IsYoungSequence(sequence)) {
+ if (IsYoungSequence(isolate, sequence)) {
*age = kNoAgeCodeAge;
*parity = NO_MARKING_PARITY;
} else {
@@ -1091,10 +1173,9 @@ void Code::PatchPlatformCodeAge(Isolate* isolate,
byte* sequence,
Code::Age age,
MarkingParity parity) {
- uint32_t young_length;
- byte* young_sequence = GetNoCodeAgeSequence(&young_length);
+ uint32_t young_length = isolate->code_aging_helper()->young_sequence_length();
if (age == kNoAgeCodeAge) {
- CopyBytes(sequence, young_sequence, young_length);
+ isolate->code_aging_helper()->CopyYoungSequenceTo(sequence);
CPU::FlushICache(sequence, young_length);
} else {
Code* stub = GetCodeAgeStub(isolate, age, parity);
diff --git a/deps/v8/src/mips/codegen-mips.h b/deps/v8/src/mips/codegen-mips.h
index efbcb3ce33..23b8fe339c 100644
--- a/deps/v8/src/mips/codegen-mips.h
+++ b/deps/v8/src/mips/codegen-mips.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_MIPS_CODEGEN_MIPS_H_
diff --git a/deps/v8/src/mips/constants-mips.cc b/deps/v8/src/mips/constants-mips.cc
index 2dd7a31f38..db6e9c63b7 100644
--- a/deps/v8/src/mips/constants-mips.cc
+++ b/deps/v8/src/mips/constants-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/mips/constants-mips.h b/deps/v8/src/mips/constants-mips.h
index dcf8b82db0..6aeb1195bb 100644
--- a/deps/v8/src/mips/constants-mips.h
+++ b/deps/v8/src/mips/constants-mips.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_MIPS_CONSTANTS_H_
#define V8_MIPS_CONSTANTS_H_
@@ -55,6 +32,18 @@ enum ArchVariants {
static const ArchVariants kArchVariant = kMips32r1;
#endif
+enum Endianness {
+ kLittle,
+ kBig
+};
+
+#if defined(V8_TARGET_LITTLE_ENDIAN)
+ static const Endianness kArchEndian = kLittle;
+#elif defined(V8_TARGET_BIG_ENDIAN)
+ static const Endianness kArchEndian = kBig;
+#else
+#error Unknown endianness
+#endif
#if(defined(__mips_hard_float) && __mips_hard_float != 0)
// Use floating-point coprocessor instructions. This flag is raised when
@@ -69,6 +58,15 @@ const bool IsMipsSoftFloatABI = true;
const bool IsMipsSoftFloatABI = true;
#endif
+#if defined(V8_TARGET_LITTLE_ENDIAN)
+const uint32_t kHoleNanUpper32Offset = 4;
+const uint32_t kHoleNanLower32Offset = 0;
+#elif defined(V8_TARGET_BIG_ENDIAN)
+const uint32_t kHoleNanUpper32Offset = 0;
+const uint32_t kHoleNanLower32Offset = 4;
+#else
+#error Unknown endianness
+#endif
// Defines constants and accessor classes to assemble, disassemble and
// simulate MIPS32 instructions.
diff --git a/deps/v8/src/mips/cpu-mips.cc b/deps/v8/src/mips/cpu-mips.cc
index 49d0b377eb..71e3ddc79f 100644
--- a/deps/v8/src/mips/cpu-mips.cc
+++ b/deps/v8/src/mips/cpu-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// CPU specific code for arm independent of OS goes here.
@@ -47,16 +24,6 @@ namespace v8 {
namespace internal {
-void CPU::SetUp() {
- CpuFeatures::Probe();
-}
-
-
-bool CPU::SupportsCrankshaft() {
- return CpuFeatures::IsSupported(FPU);
-}
-
-
void CPU::FlushICache(void* start, size_t size) {
// Nothing to do, flushing no instructions.
if (size == 0) {
diff --git a/deps/v8/src/mips/debug-mips.cc b/deps/v8/src/mips/debug-mips.cc
index b9bf69db42..fcb5643d15 100644
--- a/deps/v8/src/mips/debug-mips.cc
+++ b/deps/v8/src/mips/debug-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
@@ -37,8 +14,6 @@
namespace v8 {
namespace internal {
-#ifdef ENABLE_DEBUGGER_SUPPORT
-
bool BreakLocationIterator::IsDebugBreakAtReturn() {
return Debug::IsDebugBreakAtReturn(rinfo());
}
@@ -58,9 +33,8 @@ void BreakLocationIterator::SetDebugBreakAtReturn() {
ASSERT(Assembler::kJSReturnSequenceInstructions == 7);
CodePatcher patcher(rinfo()->pc(), Assembler::kJSReturnSequenceInstructions);
// li and Call pseudo-instructions emit two instructions each.
- patcher.masm()->li(v8::internal::t9,
- Operand(reinterpret_cast<int32_t>(
- debug_info_->GetIsolate()->debug()->debug_break_return()->entry())));
+ patcher.masm()->li(v8::internal::t9, Operand(reinterpret_cast<int32_t>(
+ debug_info_->GetIsolate()->builtins()->Return_DebugBreak()->entry())));
patcher.masm()->Call(v8::internal::t9);
patcher.masm()->nop();
patcher.masm()->nop();
@@ -105,7 +79,7 @@ void BreakLocationIterator::SetDebugBreakAtSlot() {
// call t9 (jalr t9 / nop instruction pair)
CodePatcher patcher(rinfo()->pc(), Assembler::kDebugBreakSlotInstructions);
patcher.masm()->li(v8::internal::t9, Operand(reinterpret_cast<int32_t>(
- debug_info_->GetIsolate()->debug()->debug_break_slot()->entry())));
+ debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry())));
patcher.masm()->Call(v8::internal::t9);
}
@@ -156,7 +130,7 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
__ PrepareCEntryArgs(0); // No arguments.
__ PrepareCEntryFunction(ExternalReference::debug_break(masm->isolate()));
- CEntryStub ceb(1);
+ CEntryStub ceb(masm->isolate(), 1);
__ CallStub(&ceb);
// Restore the register values from the expression stack.
@@ -188,6 +162,16 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
}
+void Debug::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
+ // Register state for CallICStub
+ // ----------- S t a t e -------------
+ // -- a1 : function
+ // -- a3 : slot in feedback array (smi)
+ // -----------------------------------
+ Generate_DebugBreakCallHelper(masm, a1.bit() | a3.bit(), 0);
+}
+
+
void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC load (from ic-mips.cc).
// ----------- S t a t e -------------
@@ -244,15 +228,6 @@ void Debug::GenerateCompareNilICDebugBreak(MacroAssembler* masm) {
}
-void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) {
- // Calling convention for IC call (from ic-mips.cc).
- // ----------- S t a t e -------------
- // -- a2: name
- // -----------------------------------
- Generate_DebugBreakCallHelper(masm, a2.bit(), 0);
-}
-
-
void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
// In places other than IC call sites it is expected that v0 is TOS which
// is an object - this is not generally the case so this should be used with
@@ -270,17 +245,6 @@ void Debug::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
}
-void Debug::GenerateCallFunctionStubRecordDebugBreak(MacroAssembler* masm) {
- // Register state for CallFunctionStub (from code-stubs-mips.cc).
- // ----------- S t a t e -------------
- // -- a1 : function
- // -- a2 : feedback array
- // -- a3 : slot in feedback array
- // -----------------------------------
- Generate_DebugBreakCallHelper(masm, a1.bit() | a2.bit() | a3.bit(), 0);
-}
-
-
void Debug::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
// Calling convention for CallConstructStub (from code-stubs-mips.cc).
// ----------- S t a t e -------------
@@ -339,9 +303,6 @@ const bool Debug::kFrameDropperSupported = false;
#undef __
-
-#endif // ENABLE_DEBUGGER_SUPPORT
-
} } // namespace v8::internal
#endif // V8_TARGET_ARCH_MIPS
diff --git a/deps/v8/src/mips/deoptimizer-mips.cc b/deps/v8/src/mips/deoptimizer-mips.cc
index 0cd5e2ccd2..4297ad1278 100644
--- a/deps/v8/src/mips/deoptimizer-mips.cc
+++ b/deps/v8/src/mips/deoptimizer-mips.cc
@@ -1,30 +1,7 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -53,7 +30,7 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
// Fail hard and early if we enter this code object again.
byte* pointer = code->FindCodeAgeSequence();
if (pointer != NULL) {
- pointer += kNoCodeAgeSequenceLength * Assembler::kInstrSize;
+ pointer += kNoCodeAgeSequenceLength;
} else {
pointer = code->instruction_start();
}
diff --git a/deps/v8/src/mips/disasm-mips.cc b/deps/v8/src/mips/disasm-mips.cc
index 1ae0340351..52f33d25d2 100644
--- a/deps/v8/src/mips/disasm-mips.cc
+++ b/deps/v8/src/mips/disasm-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// A Disassembler object is used to disassemble a block of code instruction by
// instruction. The default implementation of the NameConverter object can be
diff --git a/deps/v8/src/mips/frames-mips.cc b/deps/v8/src/mips/frames-mips.cc
index 20f0712666..205e9bcf47 100644
--- a/deps/v8/src/mips/frames-mips.cc
+++ b/deps/v8/src/mips/frames-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/mips/frames-mips.h b/deps/v8/src/mips/frames-mips.h
index 0ec2cbb864..c7b88aa5cc 100644
--- a/deps/v8/src/mips/frames-mips.h
+++ b/deps/v8/src/mips/frames-mips.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
diff --git a/deps/v8/src/mips/full-codegen-mips.cc b/deps/v8/src/mips/full-codegen-mips.cc
index 87c0764b60..ff280ce76c 100644
--- a/deps/v8/src/mips/full-codegen-mips.cc
+++ b/deps/v8/src/mips/full-codegen-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -127,10 +104,14 @@ static void EmitStackCheck(MacroAssembler* masm_,
Isolate* isolate = masm_->isolate();
Label ok;
ASSERT(scratch.is(sp) == (pointers == 0));
+ Heap::RootListIndex index;
if (pointers != 0) {
__ Subu(scratch, sp, Operand(pointers * kPointerSize));
+ index = Heap::kRealStackLimitRootIndex;
+ } else {
+ index = Heap::kStackLimitRootIndex;
}
- __ LoadRoot(stack_limit_scratch, Heap::kStackLimitRootIndex);
+ __ LoadRoot(stack_limit_scratch, index);
__ Branch(&ok, hs, scratch, Operand(stack_limit_scratch));
PredictableCodeSizeScope predictable(masm_, 4 * Assembler::kInstrSize);
__ Call(isolate->builtins()->StackCheck(), RelocInfo::CODE_TARGET);
@@ -157,8 +138,6 @@ void FullCodeGenerator::Generate() {
handler_table_ =
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
- InitializeFeedbackVector();
-
profiling_counter_ = isolate()->factory()->NewCell(
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
SetFunctionPosition(function());
@@ -245,7 +224,7 @@ void FullCodeGenerator::Generate() {
__ Push(info->scope()->GetScopeInfo());
__ CallRuntime(Runtime::kHiddenNewGlobalContext, 2);
} else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
- FastNewContextStub stub(heap_slots);
+ FastNewContextStub stub(isolate(), heap_slots);
__ CallStub(&stub);
} else {
__ push(a1);
@@ -306,7 +285,7 @@ void FullCodeGenerator::Generate() {
} else {
type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
}
- ArgumentsAccessStub stub(type);
+ ArgumentsAccessStub stub(isolate(), type);
__ CallStub(&stub);
SetVar(arguments, v0, a1, a2);
@@ -1198,12 +1177,8 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Label non_proxy;
__ bind(&fixed_array);
- Handle<Object> feedback = Handle<Object>(
- Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
- isolate());
- StoreFeedbackVectorSlot(slot, feedback);
__ li(a1, FeedbackVector());
- __ li(a2, Operand(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker)));
+ __ li(a2, Operand(TypeFeedbackInfo::MegamorphicSentinel(isolate())));
__ sw(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(slot)));
__ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check
@@ -1364,7 +1339,9 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
!pretenure &&
scope()->is_function_scope() &&
info->num_literals() == 0) {
- FastNewClosureStub stub(info->strict_mode(), info->is_generator());
+ FastNewClosureStub stub(isolate(),
+ info->strict_mode(),
+ info->is_generator());
__ li(a2, Operand(info));
__ CallStub(&stub);
} else {
@@ -1683,13 +1660,13 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
: ObjectLiteral::kNoFlags;
__ li(a0, Operand(Smi::FromInt(flags)));
int properties_count = constant_properties->length() / 2;
- if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() ||
- flags != ObjectLiteral::kFastElements ||
+ if (expr->may_store_doubles() || expr->depth() > 1 ||
+ Serializer::enabled(isolate()) || flags != ObjectLiteral::kFastElements ||
properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
__ Push(a3, a2, a1, a0);
__ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4);
} else {
- FastCloneShallowObjectStub stub(properties_count);
+ FastCloneShallowObjectStub stub(isolate(), properties_count);
__ CallStub(&stub);
}
@@ -1831,13 +1808,14 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
if (has_fast_elements && constant_elements_values->map() ==
isolate()->heap()->fixed_cow_array_map()) {
FastCloneShallowArrayStub stub(
+ isolate(),
FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS,
allocation_site_mode,
length);
__ CallStub(&stub);
__ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(),
1, a1, a2);
- } else if (expr->depth() > 1 || Serializer::enabled() ||
+ } else if (expr->depth() > 1 || Serializer::enabled(isolate()) ||
length > FastCloneShallowArrayStub::kMaximumClonedLength) {
__ li(a0, Operand(Smi::FromInt(flags)));
__ Push(a3, a2, a1, a0);
@@ -1852,7 +1830,8 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
mode = FastCloneShallowArrayStub::CLONE_ELEMENTS;
}
- FastCloneShallowArrayStub stub(mode, allocation_site_mode, length);
+ FastCloneShallowArrayStub stub(isolate(), mode, allocation_site_mode,
+ length);
__ CallStub(&stub);
}
@@ -1886,7 +1865,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
} else {
__ li(a3, Operand(Smi::FromInt(i)));
__ mov(a0, result_register());
- StoreArrayLiteralElementStub stub;
+ StoreArrayLiteralElementStub stub(isolate());
__ CallStub(&stub);
}
@@ -1902,7 +1881,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
void FullCodeGenerator::VisitAssignment(Assignment* expr) {
- ASSERT(expr->target()->IsValidLeftHandSide());
+ ASSERT(expr->target()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ Assignment");
@@ -2134,7 +2113,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ mov(a0, v0);
__ mov(a1, a0);
__ sw(a1, MemOperand(sp, 2 * kPointerSize));
- CallFunctionStub stub(1, CALL_AS_METHOD);
+ CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
__ CallStub(&stub);
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2281,7 +2260,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
Label gc_required;
Label allocated;
- Handle<Map> map(isolate()->native_context()->generator_result_map());
+ Handle<Map> map(isolate()->native_context()->iterator_result_map());
__ Allocate(map->instance_size(), v0, a2, a3, &gc_required, TAG_OBJECT);
__ jmp(&allocated);
@@ -2355,8 +2334,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
__ bind(&stub_call);
- BinaryOpICStub stub(op, mode);
- CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
+ BinaryOpICStub stub(isolate(), op, mode);
+ CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done);
@@ -2433,16 +2412,16 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
OverwriteMode mode) {
__ mov(a0, result_register());
__ pop(a1);
- BinaryOpICStub stub(op, mode);
+ BinaryOpICStub stub(isolate(), op, mode);
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
- CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
+ CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
context()->Plug(v0);
}
void FullCodeGenerator::EmitAssignment(Expression* expr) {
- ASSERT(expr->IsValidLeftHandSide());
+ ASSERT(expr->IsValidReferenceExpression());
// Left-hand side can only be a property, a global or a (parameter or local)
// slot.
@@ -2645,14 +2624,15 @@ void FullCodeGenerator::CallIC(Handle<Code> code,
// Code common for calls using the IC.
-void FullCodeGenerator::EmitCallWithIC(Call* expr) {
+void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
- ZoneList<Expression*>* args = expr->arguments();
- int arg_count = args->length();
- CallFunctionFlags flags;
+ CallIC::CallType call_type = callee->IsVariableProxy()
+ ? CallIC::FUNCTION
+ : CallIC::METHOD;
+
// Get the target function.
- if (callee->IsVariableProxy()) {
+ if (call_type == CallIC::FUNCTION) {
{ StackValueContext context(this);
EmitVariableLoad(callee->AsVariableProxy());
PrepareForBailout(callee, NO_REGISTERS);
@@ -2660,7 +2640,6 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr) {
// Push undefined as receiver. This is patched in the method prologue if it
// is a sloppy mode method.
__ Push(isolate()->factory()->undefined_value());
- flags = NO_CALL_FUNCTION_FLAGS;
} else {
// Load the function from the receiver.
ASSERT(callee->IsProperty());
@@ -2671,39 +2650,19 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr) {
__ lw(at, MemOperand(sp, 0));
__ push(at);
__ sw(v0, MemOperand(sp, kPointerSize));
- flags = CALL_AS_METHOD;
- }
-
- // Load the arguments.
- { PreservePositionScope scope(masm()->positions_recorder());
- for (int i = 0; i < arg_count; i++) {
- VisitForStackValue(args->at(i));
- }
}
- // Record source position for debugger.
- SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, flags);
- __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
- __ CallStub(&stub);
- RecordJSReturnSite(expr);
-
- // Restore context register.
- __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-
- context()->DropAndPlug(1, v0);
+ EmitCall(expr, call_type);
}
// Code common for calls using the IC.
-void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
- Expression* key) {
+void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
+ Expression* key) {
// Load the key.
VisitForAccumulatorValue(key);
Expression* callee = expr->expression();
- ZoneList<Expression*>* args = expr->arguments();
- int arg_count = args->length();
// Load the function from the receiver.
ASSERT(callee->IsProperty());
@@ -2716,28 +2675,12 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
__ push(at);
__ sw(v0, MemOperand(sp, kPointerSize));
- { PreservePositionScope scope(masm()->positions_recorder());
- for (int i = 0; i < arg_count; i++) {
- VisitForStackValue(args->at(i));
- }
- }
-
- // Record source position for debugger.
- SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, CALL_AS_METHOD);
- __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
- __ CallStub(&stub);
-
- RecordJSReturnSite(expr);
- // Restore context register.
- __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-
- context()->DropAndPlug(1, v0);
+ EmitCall(expr, CallIC::METHOD);
}
-void FullCodeGenerator::EmitCallWithStub(Call* expr) {
- // Code common for calls using the call stub.
+void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) {
+ // Load the arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope scope(masm()->positions_recorder());
@@ -2745,19 +2688,17 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr) {
VisitForStackValue(args->at(i));
}
}
- // Record source position for debugger.
- SetSourcePosition(expr->position());
- Handle<Object> uninitialized =
- TypeFeedbackInfo::UninitializedSentinel(isolate());
- StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
- __ li(a2, FeedbackVector());
+ // Record source position of the IC call.
+ SetSourcePosition(expr->position());
+ Handle<Code> ic = CallIC::initialize_stub(
+ isolate(), arg_count, call_type);
__ li(a3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
-
- // Record call targets in unoptimized code.
- CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
__ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
- __ CallStub(&stub);
+ // Don't assign a type feedback id to the IC, since type feedback is provided
+ // by the vector above.
+ CallIC(ic);
+
RecordJSReturnSite(expr);
// Restore context register.
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2831,7 +2772,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
}
// Record source position for debugger.
SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
+ CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
RecordJSReturnSite(expr);
@@ -2839,7 +2780,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
context()->DropAndPlug(1, v0);
} else if (call_type == Call::GLOBAL_CALL) {
- EmitCallWithIC(expr);
+ EmitCallWithLoadIC(expr);
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
// Call to a lookup slot (dynamically introduced variable).
VariableProxy* proxy = callee->AsVariableProxy();
@@ -2878,16 +2819,16 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// The receiver is either the global receiver or an object found
// by LoadContextSlot.
- EmitCallWithStub(expr);
+ EmitCall(expr);
} else if (call_type == Call::PROPERTY_CALL) {
Property* property = callee->AsProperty();
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
if (property->key()->IsPropertyName()) {
- EmitCallWithIC(expr);
+ EmitCallWithLoadIC(expr);
} else {
- EmitKeyedCallWithIC(expr, property->key());
+ EmitKeyedCallWithLoadIC(expr, property->key());
}
} else {
ASSERT(call_type == Call::OTHER_CALL);
@@ -2898,7 +2839,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
__ push(a1);
// Emit function call.
- EmitCallWithStub(expr);
+ EmitCall(expr);
}
#ifdef DEBUG
@@ -2935,12 +2876,8 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
__ lw(a1, MemOperand(sp, arg_count * kPointerSize));
// Record call targets in unoptimized code.
- Handle<Object> uninitialized =
- TypeFeedbackInfo::UninitializedSentinel(isolate());
- StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
if (FLAG_pretenuring_call_new) {
- StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(),
- isolate()->factory()->NewAllocationSite());
+ EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
ASSERT(expr->AllocationSiteFeedbackSlot() ==
expr->CallNewFeedbackSlot() + 1);
}
@@ -2948,8 +2885,8 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
__ li(a2, FeedbackVector());
__ li(a3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
- CallConstructStub stub(RECORD_CALL_TARGET);
- __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
+ CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
+ __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
context()->Plug(v0);
}
@@ -3324,7 +3261,7 @@ void FullCodeGenerator::EmitArguments(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(0));
__ mov(a1, v0);
__ li(a0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
- ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
+ ArgumentsAccessStub stub(isolate(), ArgumentsAccessStub::READ_ELEMENT);
__ CallStub(&stub);
context()->Plug(v0);
}
@@ -3411,31 +3348,9 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
}
-void FullCodeGenerator::EmitLog(CallRuntime* expr) {
- // Conditionally generate a log call.
- // Args:
- // 0 (literal string): The type of logging (corresponds to the flags).
- // This is used to determine whether or not to generate the log call.
- // 1 (string): Format string. Access the string at argument index 2
- // with '%2s' (see Logger::LogRuntime for all the formats).
- // 2 (array): Arguments to the format string.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT_EQ(args->length(), 3);
- if (CodeGenerator::ShouldGenerateLog(isolate(), args->at(0))) {
- VisitForStackValue(args->at(1));
- VisitForStackValue(args->at(2));
- __ CallRuntime(Runtime::kHiddenLog, 2);
- }
-
- // Finally, we're expected to leave a value on the top of the stack.
- __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
- context()->Plug(v0);
-}
-
-
void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
// Load the arguments on the stack and call the stub.
- SubStringStub stub;
+ SubStringStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 3);
VisitForStackValue(args->at(0));
@@ -3448,7 +3363,7 @@ void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) {
// Load the arguments on the stack and call the stub.
- RegExpExecStub stub;
+ RegExpExecStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 4);
VisitForStackValue(args->at(0));
@@ -3607,7 +3522,7 @@ void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
ASSERT(args->length() == 2);
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
- MathPowStub stub(MathPowStub::ON_STACK);
+ MathPowStub stub(isolate(), MathPowStub::ON_STACK);
__ CallStub(&stub);
context()->Plug(v0);
}
@@ -3650,7 +3565,7 @@ void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(0));
__ mov(a0, result_register());
- NumberToStringStub stub;
+ NumberToStringStub stub(isolate());
__ CallStub(&stub);
context()->Plug(v0);
}
@@ -3779,7 +3694,7 @@ void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) {
__ pop(a1);
__ mov(a0, result_register()); // StringAddStub requires args in a0, a1.
- StringAddStub stub(STRING_ADD_CHECK_BOTH, NOT_TENURED);
+ StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED);
__ CallStub(&stub);
context()->Plug(v0);
}
@@ -3792,32 +3707,12 @@ void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
- StringCompareStub stub;
+ StringCompareStub stub(isolate());
__ CallStub(&stub);
context()->Plug(v0);
}
-void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_log, 1);
- context()->Plug(v0);
-}
-
-
-void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_sqrt, 1);
- context()->Plug(v0);
-}
-
-
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() >= 2);
@@ -3851,7 +3746,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
- RegExpConstructResultStub stub;
+ RegExpConstructResultStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 3);
VisitForStackValue(args->at(0));
@@ -4226,7 +4121,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
// Record source position of the IC call.
SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
+ CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
@@ -4358,7 +4253,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
- ASSERT(expr->expression()->IsValidLeftHandSide());
+ ASSERT(expr->expression()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ CountOperation");
SetSourcePosition(expr->position());
@@ -4448,7 +4343,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ jmp(&stub_call);
__ bind(&slow);
}
- ToNumberStub convert_stub;
+ ToNumberStub convert_stub(isolate());
__ CallStub(&convert_stub);
// Save result for postfix expressions.
@@ -4478,8 +4373,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
// Record position before stub call.
SetSourcePosition(expr->position());
- BinaryOpICStub stub(Token::ADD, NO_OVERWRITE);
- CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId());
+ BinaryOpICStub stub(isolate(), Token::ADD, NO_OVERWRITE);
+ CallIC(stub.GetCode(), expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
@@ -4591,12 +4486,13 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
}
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
- if (check->Equals(isolate()->heap()->number_string())) {
+ Factory* factory = isolate()->factory();
+ if (String::Equals(check, factory->number_string())) {
__ JumpIfSmi(v0, if_true);
__ lw(v0, FieldMemOperand(v0, HeapObject::kMapOffset));
__ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
Split(eq, v0, Operand(at), if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->string_string())) {
+ } else if (String::Equals(check, factory->string_string())) {
__ JumpIfSmi(v0, if_false);
// Check for undetectable objects => false.
__ GetObjectType(v0, v0, a1);
@@ -4605,20 +4501,20 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ And(a1, a1, Operand(1 << Map::kIsUndetectable));
Split(eq, a1, Operand(zero_reg),
if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->symbol_string())) {
+ } else if (String::Equals(check, factory->symbol_string())) {
__ JumpIfSmi(v0, if_false);
__ GetObjectType(v0, v0, a1);
Split(eq, a1, Operand(SYMBOL_TYPE), if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->boolean_string())) {
+ } else if (String::Equals(check, factory->boolean_string())) {
__ LoadRoot(at, Heap::kTrueValueRootIndex);
__ Branch(if_true, eq, v0, Operand(at));
__ LoadRoot(at, Heap::kFalseValueRootIndex);
Split(eq, v0, Operand(at), if_true, if_false, fall_through);
} else if (FLAG_harmony_typeof &&
- check->Equals(isolate()->heap()->null_string())) {
+ String::Equals(check, factory->null_string())) {
__ LoadRoot(at, Heap::kNullValueRootIndex);
Split(eq, v0, Operand(at), if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->undefined_string())) {
+ } else if (String::Equals(check, factory->undefined_string())) {
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
__ Branch(if_true, eq, v0, Operand(at));
__ JumpIfSmi(v0, if_false);
@@ -4627,14 +4523,14 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ lbu(a1, FieldMemOperand(v0, Map::kBitFieldOffset));
__ And(a1, a1, Operand(1 << Map::kIsUndetectable));
Split(ne, a1, Operand(zero_reg), if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->function_string())) {
+ } else if (String::Equals(check, factory->function_string())) {
__ JumpIfSmi(v0, if_false);
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
__ GetObjectType(v0, v0, a1);
__ Branch(if_true, eq, a1, Operand(JS_FUNCTION_TYPE));
Split(eq, a1, Operand(JS_FUNCTION_PROXY_TYPE),
if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->object_string())) {
+ } else if (String::Equals(check, factory->object_string())) {
__ JumpIfSmi(v0, if_false);
if (!FLAG_harmony_typeof) {
__ LoadRoot(at, Heap::kNullValueRootIndex);
@@ -4686,7 +4582,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
case Token::INSTANCEOF: {
VisitForStackValue(expr->right());
- InstanceofStub stub(InstanceofStub::kNoFlags);
+ InstanceofStub stub(isolate(), InstanceofStub::kNoFlags);
__ CallStub(&stub);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
// The stub returns 0 for true.
diff --git a/deps/v8/src/mips/ic-mips.cc b/deps/v8/src/mips/ic-mips.cc
index 09ffe95c02..d78fdc6437 100644
--- a/deps/v8/src/mips/ic-mips.cc
+++ b/deps/v8/src/mips/ic-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
@@ -918,7 +895,7 @@ static void KeyedStoreGenerateGenericHelper(
// We have to see if the double version of the hole is present. If so
// go to the runtime.
__ Addu(address, elements,
- Operand(FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32)
+ Operand(FixedDoubleArray::kHeaderSize + kHoleNanUpper32Offset
- kHeapObjectTag));
__ sll(at, key, kPointerSizeLog2);
__ addu(address, address, at);
diff --git a/deps/v8/src/mips/lithium-codegen-mips.cc b/deps/v8/src/mips/lithium-codegen-mips.cc
index 970a1bfc25..95ee3a6c12 100644
--- a/deps/v8/src/mips/lithium-codegen-mips.cc
+++ b/deps/v8/src/mips/lithium-codegen-mips.cc
@@ -86,13 +86,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
PopulateDeoptimizationData(code);
- info()->CommitDependencies(code);
-}
-
-
-void LChunkBuilder::Abort(BailoutReason reason) {
- info()->set_bailout_reason(reason);
- status_ = ABORTED;
}
@@ -203,7 +196,7 @@ bool LCodeGen::GeneratePrologue() {
Comment(";;; Allocate local context");
// Argument to NewContext is the function, which is in a1.
if (heap_slots <= FastNewContextStub::kMaximumSlots) {
- FastNewContextStub stub(heap_slots);
+ FastNewContextStub stub(isolate(), heap_slots);
__ CallStub(&stub);
} else {
__ push(a1);
@@ -744,6 +737,7 @@ void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment,
Safepoint::DeoptMode mode) {
+ environment->set_has_been_used();
if (!environment->HasBeenRegistered()) {
// Physical stack frame layout:
// -x ............. -4 0 ..................................... y
@@ -860,7 +854,7 @@ void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
int length = deoptimizations_.length();
if (length == 0) return;
Handle<DeoptimizationInputData> data =
- factory()->NewDeoptimizationInputData(length, TENURED);
+ DeoptimizationInputData::New(isolate(), length, TENURED);
Handle<ByteArray> translations =
translations_.CreateByteArray(isolate()->factory());
@@ -1045,18 +1039,18 @@ void LCodeGen::DoCallStub(LCallStub* instr) {
ASSERT(ToRegister(instr->result()).is(v0));
switch (instr->hydrogen()->major_key()) {
case CodeStub::RegExpExec: {
- RegExpExecStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ RegExpExecStub stub(isolate());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
case CodeStub::SubString: {
- SubStringStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ SubStringStub stub(isolate());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
case CodeStub::StringCompare: {
- StringCompareStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ StringCompareStub stub(isolate());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
default:
@@ -1174,7 +1168,7 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
Register dividend = ToRegister(instr->dividend());
int32_t divisor = instr->divisor();
Register result = ToRegister(instr->result());
- ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor))));
+ ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor)));
ASSERT(!result.is(dividend));
// Check for (0 / -x) that will produce negative zero.
@@ -1242,26 +1236,27 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
}
+// TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI.
void LCodeGen::DoDivI(LDivI* instr) {
HBinaryOperation* hdiv = instr->hydrogen();
- const Register left = ToRegister(instr->left());
- const Register right = ToRegister(instr->right());
+ Register dividend = ToRegister(instr->dividend());
+ Register divisor = ToRegister(instr->divisor());
const Register result = ToRegister(instr->result());
// On MIPS div is asynchronous - it will run in the background while we
// check for special cases.
- __ div(left, right);
+ __ div(dividend, divisor);
// Check for x / 0.
if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
- DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg));
+ DeoptimizeIf(eq, instr->environment(), divisor, Operand(zero_reg));
}
// Check for (0 / -x) that will produce negative zero.
if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
Label left_not_zero;
- __ Branch(&left_not_zero, ne, left, Operand(zero_reg));
- DeoptimizeIf(lt, instr->environment(), right, Operand(zero_reg));
+ __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg));
+ DeoptimizeIf(lt, instr->environment(), divisor, Operand(zero_reg));
__ bind(&left_not_zero);
}
@@ -1269,23 +1264,12 @@ void LCodeGen::DoDivI(LDivI* instr) {
if (hdiv->CheckFlag(HValue::kCanOverflow) &&
!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
Label left_not_min_int;
- __ Branch(&left_not_min_int, ne, left, Operand(kMinInt));
- DeoptimizeIf(eq, instr->environment(), right, Operand(-1));
+ __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt));
+ DeoptimizeIf(eq, instr->environment(), divisor, Operand(-1));
__ bind(&left_not_min_int);
}
- if (hdiv->IsMathFloorOfDiv()) {
- // We performed a truncating division. Correct the result if necessary.
- Label done;
- Register remainder = scratch0();
- __ mfhi(remainder);
- __ mflo(result);
- __ Branch(&done, eq, remainder, Operand(zero_reg), USE_DELAY_SLOT);
- __ Xor(remainder, remainder, Operand(right));
- __ Branch(&done, ge, remainder, Operand(zero_reg));
- __ Subu(result, result, Operand(1));
- __ bind(&done);
- } else if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
+ if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
__ mfhi(result);
DeoptimizeIf(ne, instr->environment(), result, Operand(zero_reg));
__ mflo(result);
@@ -1331,25 +1315,27 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg));
}
- if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
- // Note that we could emit branch-free code, but that would need one more
- // register.
- __ Xor(at, scratch, result);
- if (divisor == -1) {
- DeoptimizeIf(ge, instr->environment(), at, Operand(zero_reg));
- __ sra(result, dividend, shift);
- } else {
- Label no_overflow, done;
- __ Branch(&no_overflow, lt, at, Operand(zero_reg));
- __ li(result, Operand(kMinInt / divisor));
- __ Branch(&done);
- __ bind(&no_overflow);
- __ sra(result, dividend, shift);
- __ bind(&done);
- }
- } else {
+
+ // If the negation could not overflow, simply shifting is OK.
+ if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
__ sra(result, dividend, shift);
+ return;
+ }
+
+ // Dividing by -1 is basically negation, unless we overflow.
+ __ Xor(at, scratch, result);
+ if (divisor == -1) {
+ DeoptimizeIf(ge, instr->environment(), at, Operand(zero_reg));
+ return;
}
+
+ Label no_overflow, done;
+ __ Branch(&no_overflow, lt, at, Operand(zero_reg));
+ __ li(result, Operand(kMinInt / divisor));
+ __ Branch(&done);
+ __ bind(&no_overflow);
+ __ sra(result, dividend, shift);
+ __ bind(&done);
}
@@ -1398,6 +1384,52 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
}
+// TODO(svenpanne) Refactor this to avoid code duplication with DoDivI.
+void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
+ HBinaryOperation* hdiv = instr->hydrogen();
+ Register dividend = ToRegister(instr->dividend());
+ Register divisor = ToRegister(instr->divisor());
+ const Register result = ToRegister(instr->result());
+
+ // On MIPS div is asynchronous - it will run in the background while we
+ // check for special cases.
+ __ div(dividend, divisor);
+
+ // Check for x / 0.
+ if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
+ DeoptimizeIf(eq, instr->environment(), divisor, Operand(zero_reg));
+ }
+
+ // Check for (0 / -x) that will produce negative zero.
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ Label left_not_zero;
+ __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg));
+ DeoptimizeIf(lt, instr->environment(), divisor, Operand(zero_reg));
+ __ bind(&left_not_zero);
+ }
+
+ // Check for (kMinInt / -1).
+ if (hdiv->CheckFlag(HValue::kCanOverflow) &&
+ !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
+ Label left_not_min_int;
+ __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt));
+ DeoptimizeIf(eq, instr->environment(), divisor, Operand(-1));
+ __ bind(&left_not_min_int);
+ }
+
+ // We performed a truncating division. Correct the result if necessary.
+ Label done;
+ Register remainder = scratch0();
+ __ mfhi(remainder);
+ __ mflo(result);
+ __ Branch(&done, eq, remainder, Operand(zero_reg), USE_DELAY_SLOT);
+ __ Xor(remainder, remainder, Operand(divisor));
+ __ Branch(&done, ge, remainder, Operand(zero_reg));
+ __ Subu(result, result, Operand(1));
+ __ bind(&done);
+}
+
+
void LCodeGen::DoMulI(LMulI* instr) {
Register scratch = scratch0();
Register result = ToRegister(instr->result());
@@ -1696,9 +1728,16 @@ void LCodeGen::DoConstantE(LConstantE* instr) {
void LCodeGen::DoConstantT(LConstantT* instr) {
- Handle<Object> value = instr->value(isolate());
+ Handle<Object> object = instr->value(isolate());
AllowDeferredHandleDereference smi_check;
- __ li(ToRegister(instr->result()), value);
+ if (instr->hydrogen()->HasObjectMap()) {
+ Handle<Map> object_map = instr->hydrogen()->ObjectMap().handle();
+ ASSERT(object->IsHeapObject());
+ ASSERT(!object_map->is_stable() ||
+ *object_map == Handle<HeapObject>::cast(object)->map());
+ USE(object_map);
+ }
+ __ li(ToRegister(instr->result()), object);
}
@@ -1972,8 +2011,8 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
ASSERT(ToRegister(instr->right()).is(a0));
ASSERT(ToRegister(instr->result()).is(v0));
- BinaryOpICStub stub(instr->op(), NO_OVERWRITE);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
// Other arch use a nop here, to signal that there is no inlined
// patchable code. Mips does not need the nop, since our marker
// instruction (andi zero_reg) will never be used in normal code.
@@ -2614,8 +2653,8 @@ void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
Register result = ToRegister(instr->result());
ASSERT(result.is(v0));
- InstanceofStub stub(InstanceofStub::kArgsInRegisters);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
__ Branch(&true_label, eq, result, Operand(zero_reg));
__ li(result, Operand(factory()->false_value()));
@@ -2715,7 +2754,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
flags | InstanceofStub::kCallSiteInlineCheck);
flags = static_cast<InstanceofStub::Flags>(
flags | InstanceofStub::kReturnTrueFalseObject);
- InstanceofStub stub(flags);
+ InstanceofStub stub(isolate(), flags);
PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
LoadContextFromDeferred(instr->context());
@@ -2735,7 +2774,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
__ li(temp, Operand(delta * kPointerSize), CONSTANT_SIZE);
__ StoreToSafepointRegisterSlot(temp, temp);
}
- CallCodeGeneric(stub.GetCode(isolate()),
+ CallCodeGeneric(stub.GetCode(),
RelocInfo::CODE_TARGET,
instr,
RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
@@ -3180,7 +3219,7 @@ void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
__ ldc1(result, MemOperand(scratch));
if (instr->hydrogen()->RequiresHoleCheck()) {
- __ lw(scratch, MemOperand(scratch, sizeof(kHoleNanLower32)));
+ __ lw(scratch, MemOperand(scratch, kHoleNanUpper32Offset));
DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32));
}
}
@@ -3259,7 +3298,8 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key,
__ Addu(scratch0(), scratch0(), Operand(base_offset));
} else {
ASSERT_EQ(-1, shift_size);
- __ srl(scratch0(), key, 1);
+ // Key can be negative, so using sra here.
+ __ sra(scratch0(), key, 1);
__ Addu(scratch0(), scratch0(), Operand(base_offset));
}
__ Addu(scratch0(), base, scratch0());
@@ -3808,7 +3848,7 @@ void LCodeGen::DoPower(LPower* instr) {
ASSERT(ToDoubleRegister(instr->result()).is(f0));
if (exponent_type.IsSmi()) {
- MathPowStub stub(MathPowStub::TAGGED);
+ MathPowStub stub(isolate(), MathPowStub::TAGGED);
__ CallStub(&stub);
} else if (exponent_type.IsTagged()) {
Label no_deopt;
@@ -3817,14 +3857,14 @@ void LCodeGen::DoPower(LPower* instr) {
__ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
DeoptimizeIf(ne, instr->environment(), t3, Operand(at));
__ bind(&no_deopt);
- MathPowStub stub(MathPowStub::TAGGED);
+ MathPowStub stub(isolate(), MathPowStub::TAGGED);
__ CallStub(&stub);
} else if (exponent_type.IsInteger32()) {
- MathPowStub stub(MathPowStub::INTEGER);
+ MathPowStub stub(isolate(), MathPowStub::INTEGER);
__ CallStub(&stub);
} else {
ASSERT(exponent_type.IsDouble());
- MathPowStub stub(MathPowStub::DOUBLE);
+ MathPowStub stub(isolate(), MathPowStub::DOUBLE);
__ CallStub(&stub);
}
}
@@ -3928,8 +3968,8 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
ASSERT(ToRegister(instr->result()).is(v0));
int arity = instr->arity();
- CallFunctionStub stub(arity, instr->hydrogen()->function_flags());
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
@@ -3941,8 +3981,8 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
__ li(a0, Operand(instr->arity()));
// No cell in a2 for construct type feedback in optimized code
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
- CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
}
@@ -3960,8 +4000,8 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
: DONT_OVERRIDE;
if (instr->arity() == 0) {
- ArrayNoArgumentConstructorStub stub(kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
} else if (instr->arity() == 1) {
Label done;
if (IsFastPackedElementsKind(kind)) {
@@ -3972,18 +4012,20 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
__ Branch(&packed_case, eq, t1, Operand(zero_reg));
ElementsKind holey_kind = GetHoleyElementsKind(kind);
- ArraySingleArgumentConstructorStub stub(holey_kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArraySingleArgumentConstructorStub stub(isolate(),
+ holey_kind,
+ override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
__ jmp(&done);
__ bind(&packed_case);
}
- ArraySingleArgumentConstructorStub stub(kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
__ bind(&done);
} else {
- ArrayNArgumentsConstructorStub stub(kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
}
}
@@ -4031,7 +4073,6 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
return;
}
- Handle<Map> transition = instr->transition();
SmiCheck check_needed =
instr->hydrogen()->value()->IsHeapObject()
? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
@@ -4045,19 +4086,21 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
__ SmiTst(value, scratch);
DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg));
- // We know that value is a smi now, so we can omit the check below.
+ // We know now that value is not a smi, so we can omit the check below.
check_needed = OMIT_SMI_CHECK;
}
} else if (representation.IsDouble()) {
- ASSERT(transition.is_null());
ASSERT(access.IsInobject());
+ ASSERT(!instr->hydrogen()->has_transition());
ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
DoubleRegister value = ToDoubleRegister(instr->value());
__ sdc1(value, FieldMemOperand(object, offset));
return;
}
- if (!transition.is_null()) {
+ if (instr->hydrogen()->has_transition()) {
+ Handle<Map> transition = instr->hydrogen()->transition_map();
+ AddDeprecationDependency(transition);
__ li(scratch, Operand(transition));
__ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
@@ -4122,42 +4165,25 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
}
-void LCodeGen::ApplyCheckIf(Condition condition,
- LBoundsCheck* check,
- Register src1,
- const Operand& src2) {
- if (FLAG_debug_code && check->hydrogen()->skip_check()) {
+void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
+ Condition cc = instr->hydrogen()->allow_equality() ? hi : hs;
+ Operand operand(0);
+ Register reg;
+ if (instr->index()->IsConstantOperand()) {
+ operand = ToOperand(instr->index());
+ reg = ToRegister(instr->length());
+ cc = ReverseCondition(cc);
+ } else {
+ reg = ToRegister(instr->index());
+ operand = ToOperand(instr->length());
+ }
+ if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
Label done;
- __ Branch(&done, NegateCondition(condition), src1, src2);
+ __ Branch(&done, NegateCondition(cc), reg, operand);
__ stop("eliminated bounds check failed");
__ bind(&done);
} else {
- DeoptimizeIf(condition, check->environment(), src1, src2);
- }
-}
-
-
-void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
- if (instr->hydrogen()->skip_check()) return;
-
- Condition condition = instr->hydrogen()->allow_equality() ? hi : hs;
- if (instr->index()->IsConstantOperand()) {
- int constant_index =
- ToInteger32(LConstantOperand::cast(instr->index()));
- if (instr->hydrogen()->length()->representation().IsSmi()) {
- __ li(at, Operand(Smi::FromInt(constant_index)));
- } else {
- __ li(at, Operand(constant_index));
- }
- ApplyCheckIf(condition,
- instr,
- at,
- Operand(ToRegister(instr->length())));
- } else {
- ApplyCheckIf(condition,
- instr,
- ToRegister(instr->index()),
- Operand(ToRegister(instr->length())));
+ DeoptimizeIf(cc, instr->environment(), reg, operand);
}
}
@@ -4401,16 +4427,16 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
__ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
scratch, GetRAState(), kDontSaveFPRegs);
} else {
+ ASSERT(object_reg.is(a0));
ASSERT(ToRegister(instr->context()).is(cp));
PushSafepointRegistersScope scope(
this, Safepoint::kWithRegistersAndDoubles);
- __ mov(a0, object_reg);
__ li(a1, Operand(to_map));
bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
- TransitionElementsKindStub stub(from_kind, to_kind, is_js_array);
+ TransitionElementsKindStub stub(isolate(), from_kind, to_kind, is_js_array);
__ CallStub(&stub);
RecordSafepointWithRegistersAndDoubles(
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
+ instr->pointer_map(), 0, Safepoint::kLazyDeopt);
}
__ bind(&not_applicable);
}
@@ -4431,9 +4457,10 @@ void LCodeGen::DoStringAdd(LStringAdd* instr) {
ASSERT(ToRegister(instr->context()).is(cp));
ASSERT(ToRegister(instr->left()).is(a1));
ASSERT(ToRegister(instr->right()).is(a0));
- StringAddStub stub(instr->hydrogen()->flags(),
+ StringAddStub stub(isolate(),
+ instr->hydrogen()->flags(),
instr->hydrogen()->pretenure_flag());
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
@@ -5144,7 +5171,14 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
Register object_;
};
- if (instr->hydrogen()->CanOmitMapChecks()) return;
+ if (instr->hydrogen()->IsStabilityCheck()) {
+ const UniqueSet<Map>* maps = instr->hydrogen()->maps();
+ for (int i = 0; i < maps->size(); ++i) {
+ AddStabilityDependency(maps->at(i).handle());
+ }
+ return;
+ }
+
Register map_reg = scratch0();
LOperand* input = instr->value();
ASSERT(input->IsRegister());
@@ -5152,20 +5186,20 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
__ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
DeferredCheckMaps* deferred = NULL;
- if (instr->hydrogen()->has_migration_target()) {
+ if (instr->hydrogen()->HasMigrationTarget()) {
deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
__ bind(deferred->check_maps());
}
- UniqueSet<Map> map_set = instr->hydrogen()->map_set();
+ const UniqueSet<Map>* maps = instr->hydrogen()->maps();
Label success;
- for (int i = 0; i < map_set.size() - 1; i++) {
- Handle<Map> map = map_set.at(i).handle();
+ for (int i = 0; i < maps->size() - 1; i++) {
+ Handle<Map> map = maps->at(i).handle();
__ CompareMapAndBranch(map_reg, map, &success, eq, &success);
}
- Handle<Map> map = map_set.at(map_set.size() - 1).handle();
+ Handle<Map> map = maps->at(maps->size() - 1).handle();
// Do the CompareMap() directly within the Branch() and DeoptimizeIf().
- if (instr->hydrogen()->has_migration_target()) {
+ if (instr->hydrogen()->HasMigrationTarget()) {
__ Branch(deferred->entry(), ne, map_reg, Operand(map));
} else {
DeoptimizeIf(ne, instr->environment(), map_reg, Operand(map));
@@ -5333,7 +5367,13 @@ void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
__ push(size);
} else {
int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
- __ Push(Smi::FromInt(size));
+ if (size >= 0 && size <= Smi::kMaxValue) {
+ __ Push(Smi::FromInt(size));
+ } else {
+ // We should never get here at runtime => abort
+ __ stop("invalid allocation size");
+ return;
+ }
}
int flags = AllocateDoubleAlignFlag::encode(
@@ -5423,10 +5463,11 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
// space for nested functions that don't need literals cloning.
bool pretenure = instr->hydrogen()->pretenure();
if (!pretenure && instr->hydrogen()->has_no_literals()) {
- FastNewClosureStub stub(instr->hydrogen()->strict_mode(),
+ FastNewClosureStub stub(isolate(),
+ instr->hydrogen()->strict_mode(),
instr->hydrogen()->is_generator());
__ li(a2, Operand(instr->hydrogen()->shared_info()));
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
} else {
__ li(a2, Operand(instr->hydrogen()->shared_info()));
__ li(a1, Operand(pretenure ? factory()->true_value()
@@ -5478,7 +5519,8 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
// register.
Condition final_branch_condition = kNoCondition;
Register scratch = scratch0();
- if (type_name->Equals(heap()->number_string())) {
+ Factory* factory = isolate()->factory();
+ if (String::Equals(type_name, factory->number_string())) {
__ JumpIfSmi(input, true_label);
__ lw(input, FieldMemOperand(input, HeapObject::kMapOffset));
__ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
@@ -5486,7 +5528,7 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
cmp2 = Operand(at);
final_branch_condition = eq;
- } else if (type_name->Equals(heap()->string_string())) {
+ } else if (String::Equals(type_name, factory->string_string())) {
__ JumpIfSmi(input, false_label);
__ GetObjectType(input, input, scratch);
__ Branch(USE_DELAY_SLOT, false_label,
@@ -5499,14 +5541,14 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
cmp2 = Operand(zero_reg);
final_branch_condition = eq;
- } else if (type_name->Equals(heap()->symbol_string())) {
+ } else if (String::Equals(type_name, factory->symbol_string())) {
__ JumpIfSmi(input, false_label);
__ GetObjectType(input, input, scratch);
cmp1 = scratch;
cmp2 = Operand(SYMBOL_TYPE);
final_branch_condition = eq;
- } else if (type_name->Equals(heap()->boolean_string())) {
+ } else if (String::Equals(type_name, factory->boolean_string())) {
__ LoadRoot(at, Heap::kTrueValueRootIndex);
__ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input));
__ LoadRoot(at, Heap::kFalseValueRootIndex);
@@ -5514,13 +5556,14 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
cmp2 = Operand(input);
final_branch_condition = eq;
- } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) {
+ } else if (FLAG_harmony_typeof &&
+ String::Equals(type_name, factory->null_string())) {
__ LoadRoot(at, Heap::kNullValueRootIndex);
cmp1 = at;
cmp2 = Operand(input);
final_branch_condition = eq;
- } else if (type_name->Equals(heap()->undefined_string())) {
+ } else if (String::Equals(type_name, factory->undefined_string())) {
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
__ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input));
// The first instruction of JumpIfSmi is an And - it is safe in the delay
@@ -5534,7 +5577,7 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
cmp2 = Operand(zero_reg);
final_branch_condition = ne;
- } else if (type_name->Equals(heap()->function_string())) {
+ } else if (String::Equals(type_name, factory->function_string())) {
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
__ JumpIfSmi(input, false_label);
__ GetObjectType(input, scratch, input);
@@ -5543,7 +5586,7 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
cmp2 = Operand(JS_FUNCTION_PROXY_TYPE);
final_branch_condition = eq;
- } else if (type_name->Equals(heap()->object_string())) {
+ } else if (String::Equals(type_name, factory->object_string())) {
__ JumpIfSmi(input, false_label);
if (!FLAG_harmony_typeof) {
__ LoadRoot(at, Heap::kNullValueRootIndex);
@@ -5792,13 +5835,60 @@ void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
}
+void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
+ Register result,
+ Register object,
+ Register index) {
+ PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
+ __ Push(object, index);
+ __ mov(cp, zero_reg);
+ __ CallRuntimeSaveDoubles(Runtime::kLoadMutableDouble);
+ RecordSafepointWithRegisters(
+ instr->pointer_map(), 2, Safepoint::kNoLazyDeopt);
+ __ StoreToSafepointRegisterSlot(v0, result);
+}
+
+
void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
+ class DeferredLoadMutableDouble V8_FINAL : public LDeferredCode {
+ public:
+ DeferredLoadMutableDouble(LCodeGen* codegen,
+ LLoadFieldByIndex* instr,
+ Register result,
+ Register object,
+ Register index)
+ : LDeferredCode(codegen),
+ instr_(instr),
+ result_(result),
+ object_(object),
+ index_(index) {
+ }
+ virtual void Generate() V8_OVERRIDE {
+ codegen()->DoDeferredLoadMutableDouble(instr_, result_, object_, index_);
+ }
+ virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
+ private:
+ LLoadFieldByIndex* instr_;
+ Register result_;
+ Register object_;
+ Register index_;
+ };
+
Register object = ToRegister(instr->object());
Register index = ToRegister(instr->index());
Register result = ToRegister(instr->result());
Register scratch = scratch0();
+ DeferredLoadMutableDouble* deferred;
+ deferred = new(zone()) DeferredLoadMutableDouble(
+ this, instr, result, object, index);
+
Label out_of_object, done;
+
+ __ And(scratch, index, Operand(Smi::FromInt(1)));
+ __ Branch(deferred->entry(), ne, scratch, Operand(zero_reg));
+ __ sra(index, index, 1);
+
__ Branch(USE_DELAY_SLOT, &out_of_object, lt, index, Operand(zero_reg));
__ sll(scratch, index, kPointerSizeLog2 - kSmiTagSize); // In delay slot.
@@ -5814,6 +5904,7 @@ void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
__ Subu(scratch, result, scratch);
__ lw(result, FieldMemOperand(scratch,
FixedArray::kHeaderSize - kPointerSize));
+ __ bind(deferred->exit());
__ bind(&done);
}
diff --git a/deps/v8/src/mips/lithium-codegen-mips.h b/deps/v8/src/mips/lithium-codegen-mips.h
index 63f0661ae5..7c52d8182e 100644
--- a/deps/v8/src/mips/lithium-codegen-mips.h
+++ b/deps/v8/src/mips/lithium-codegen-mips.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_MIPS_LITHIUM_CODEGEN_MIPS_H_
#define V8_MIPS_LITHIUM_CODEGEN_MIPS_H_
@@ -34,7 +11,7 @@
#include "lithium-codegen.h"
#include "safepoint-table.h"
#include "scopes.h"
-#include "v8utils.h"
+#include "utils.h"
namespace v8 {
namespace internal {
@@ -140,6 +117,10 @@ class LCodeGen: public LCodeGenBase {
Label* map_check);
void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
+ void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
+ Register result,
+ Register object,
+ Register index);
// Parallel move support.
void DoParallelMove(LParallelMove* move);
@@ -182,8 +163,6 @@ class LCodeGen: public LCodeGenBase {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
- void Abort(BailoutReason reason);
-
void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
void SaveCallerDoubles();
@@ -259,10 +238,6 @@ class LCodeGen: public LCodeGenBase {
LEnvironment* environment,
Register src1 = zero_reg,
const Operand& src2 = Operand(zero_reg));
- void ApplyCheckIf(Condition condition,
- LBoundsCheck* check,
- Register src1 = zero_reg,
- const Operand& src2 = Operand(zero_reg));
void AddToTranslation(LEnvironment* environment,
Translation* translation,
@@ -423,13 +398,15 @@ class LCodeGen: public LCodeGenBase {
switch (codegen_->expected_safepoint_kind_) {
case Safepoint::kWithRegisters: {
- StoreRegistersStateStub stub1(kDontSaveFPRegs);
+ StoreRegistersStateStub stub1(codegen_->masm_->isolate(),
+ kDontSaveFPRegs);
codegen_->masm_->push(ra);
codegen_->masm_->CallStub(&stub1);
break;
}
case Safepoint::kWithRegistersAndDoubles: {
- StoreRegistersStateStub stub2(kSaveFPRegs);
+ StoreRegistersStateStub stub2(codegen_->masm_->isolate(),
+ kSaveFPRegs);
codegen_->masm_->push(ra);
codegen_->masm_->CallStub(&stub2);
break;
@@ -444,13 +421,15 @@ class LCodeGen: public LCodeGenBase {
ASSERT((kind & Safepoint::kWithRegisters) != 0);
switch (kind) {
case Safepoint::kWithRegisters: {
- RestoreRegistersStateStub stub1(kDontSaveFPRegs);
+ RestoreRegistersStateStub stub1(codegen_->masm_->isolate(),
+ kDontSaveFPRegs);
codegen_->masm_->push(ra);
codegen_->masm_->CallStub(&stub1);
break;
}
case Safepoint::kWithRegistersAndDoubles: {
- RestoreRegistersStateStub stub2(kSaveFPRegs);
+ RestoreRegistersStateStub stub2(codegen_->masm_->isolate(),
+ kSaveFPRegs);
codegen_->masm_->push(ra);
codegen_->masm_->CallStub(&stub2);
break;
diff --git a/deps/v8/src/mips/lithium-gap-resolver-mips.cc b/deps/v8/src/mips/lithium-gap-resolver-mips.cc
index 3ee74866c7..69af8b7ee3 100644
--- a/deps/v8/src/mips/lithium-gap-resolver-mips.cc
+++ b/deps/v8/src/mips/lithium-gap-resolver-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/mips/lithium-gap-resolver-mips.h b/deps/v8/src/mips/lithium-gap-resolver-mips.h
index ea1ea3cbbf..f3f6b7d61e 100644
--- a/deps/v8/src/mips/lithium-gap-resolver-mips.h
+++ b/deps/v8/src/mips/lithium-gap-resolver-mips.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_MIPS_LITHIUM_GAP_RESOLVER_MIPS_H_
#define V8_MIPS_LITHIUM_GAP_RESOLVER_MIPS_H_
diff --git a/deps/v8/src/mips/lithium-mips.cc b/deps/v8/src/mips/lithium-mips.cc
index 752f67673d..eb960a4bb2 100644
--- a/deps/v8/src/mips/lithium-mips.cc
+++ b/deps/v8/src/mips/lithium-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -451,7 +428,7 @@ LPlatformChunk* LChunkBuilder::Build() {
}
-void LCodeGen::Abort(BailoutReason reason) {
+void LChunkBuilder::Abort(BailoutReason reason) {
info()->set_bailout_reason(reason);
status_ = ABORTED;
}
@@ -628,6 +605,8 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
!hinstr->HasObservableSideEffects();
if (needs_environment && !instr->HasEnvironment()) {
instr = AssignEnvironment(instr);
+ // We can't really figure out if the environment is needed or not.
+ instr->environment()->set_has_been_used();
}
return instr;
@@ -879,7 +858,8 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
// the it was just a plain use), so it is free to move the split child into
// the same register that is used for the use-at-start.
// See https://code.google.com/p/chromium/issues/detail?id=201590
- if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) {
+ if (!(instr->ClobbersRegisters() &&
+ instr->ClobbersDoubleRegisters(isolate()))) {
int fixed = 0;
int used_at_start = 0;
for (UseIterator it(instr); !it.Done(); it.Advance()) {
@@ -939,18 +919,20 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
if (goto_instr != NULL) return goto_instr;
HValue* value = instr->value();
- LBranch* result = new(zone()) LBranch(UseRegister(value));
- // Tagged values that are not known smis or booleans require a
- // deoptimization environment. If the instruction is generic no
- // environment is needed since all cases are handled.
- Representation rep = value->representation();
+ Representation r = value->representation();
HType type = value->type();
ToBooleanStub::Types expected = instr->expected_input_types();
- if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() &&
- !expected.IsGeneric()) {
- return AssignEnvironment(result);
+ if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic();
+
+ bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() ||
+ type.IsJSArray() || type.IsHeapNumber() || type.IsString();
+ LInstruction* branch = new(zone()) LBranch(UseRegister(value));
+ if (!easy_case &&
+ ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) ||
+ !expected.IsGeneric())) {
+ branch = AssignEnvironment(branch);
}
- return result;
+ return branch;
}
@@ -1162,8 +1144,11 @@ LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
? NULL
: UseFixed(instr->context(), cp);
LOperand* input = UseRegister(instr->value());
- LMathAbs* result = new(zone()) LMathAbs(context, input);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ LInstruction* result =
+ DefineAsRegister(new(zone()) LMathAbs(context, input));
+ if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result);
+ if (!r.IsDouble()) result = AssignEnvironment(result);
+ return result;
}
@@ -1290,14 +1275,23 @@ LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) {
}
-LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
+LInstruction* LChunkBuilder::DoDivI(HDiv* instr) {
ASSERT(instr->representation().IsSmiOrInteger32());
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* dividend = UseRegister(instr->left());
LOperand* divisor = UseRegister(instr->right());
- LDivI* div = new(zone()) LDivI(dividend, divisor);
- return AssignEnvironment(DefineAsRegister(div));
+ LInstruction* result =
+ DefineAsRegister(new(zone()) LDivI(dividend, divisor));
+ if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+ instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+ (instr->CheckFlag(HValue::kCanOverflow) &&
+ !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) ||
+ (!instr->IsMathFloorOfDiv() &&
+ !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -1351,13 +1345,24 @@ LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
}
+LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
+ ASSERT(instr->representation().IsSmiOrInteger32());
+ ASSERT(instr->left()->representation().Equals(instr->representation()));
+ ASSERT(instr->right()->representation().Equals(instr->representation()));
+ LOperand* dividend = UseRegister(instr->left());
+ LOperand* divisor = UseRegister(instr->right());
+ LFlooringDivI* div = new(zone()) LFlooringDivI(dividend, divisor);
+ return AssignEnvironment(DefineAsRegister(div));
+}
+
+
LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
if (instr->RightIsPowerOf2()) {
return DoFlooringDivByPowerOf2I(instr);
} else if (instr->right()->IsConstant()) {
return DoFlooringDivByConstI(instr);
} else {
- return DoDivI(instr);
+ return DoFlooringDivI(instr);
}
}
@@ -1599,6 +1604,8 @@ LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
LInstruction* LChunkBuilder::DoCompareNumericAndBranch(
HCompareNumericAndBranch* instr) {
+ LInstruction* goto_instr = CheckElideControlInstruction(instr);
+ if (goto_instr != NULL) return goto_instr;
Representation r = instr->representation();
if (r.IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().Equals(r));
@@ -1753,9 +1760,16 @@ LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
- LOperand* value = UseRegisterOrConstantAtStart(instr->index());
- LOperand* length = UseRegister(instr->length());
- return AssignEnvironment(new(zone()) LBoundsCheck(value, length));
+ if (!FLAG_debug_code && instr->skip_check()) return NULL;
+ LOperand* index = UseRegisterOrConstantAtStart(instr->index());
+ LOperand* length = !index->IsConstantOperand()
+ ? UseRegisterOrConstantAtStart(instr->length())
+ : UseRegisterAtStart(instr->length());
+ LInstruction* result = new(zone()) LBoundsCheck(index, length);
+ if (!FLAG_debug_code || !instr->skip_check()) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -1789,20 +1803,21 @@ LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
LInstruction* LChunkBuilder::DoChange(HChange* instr) {
Representation from = instr->from();
Representation to = instr->to();
+ HValue* val = instr->value();
if (from.IsSmi()) {
if (to.IsTagged()) {
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
return DefineSameAsFirst(new(zone()) LDummyUse(value));
}
from = Representation::Tagged();
}
if (from.IsTagged()) {
if (to.IsDouble()) {
- LOperand* value = UseRegister(instr->value());
- LNumberUntagD* res = new(zone()) LNumberUntagD(value);
- return AssignEnvironment(DefineAsRegister(res));
+ LOperand* value = UseRegister(val);
+ LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value));
+ if (!val->representation().IsSmi()) result = AssignEnvironment(result);
+ return result;
} else if (to.IsSmi()) {
- HValue* val = instr->value();
LOperand* value = UseRegister(val);
if (val->type().IsSmi()) {
return DefineSameAsFirst(new(zone()) LDummyUse(value));
@@ -1810,66 +1825,59 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
} else {
ASSERT(to.IsInteger32());
- LOperand* value = NULL;
- LInstruction* res = NULL;
- HValue* val = instr->value();
if (val->type().IsSmi() || val->representation().IsSmi()) {
- value = UseRegisterAtStart(val);
- res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
+ LOperand* value = UseRegisterAtStart(val);
+ return DefineAsRegister(new(zone()) LSmiUntag(value, false));
} else {
- value = UseRegister(val);
+ LOperand* value = UseRegister(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = FixedTemp(f22);
- res = DefineSameAsFirst(new(zone()) LTaggedToI(value,
- temp1,
- temp2));
- res = AssignEnvironment(res);
+ LInstruction* result =
+ DefineSameAsFirst(new(zone()) LTaggedToI(value, temp1, temp2));
+ if (!val->representation().IsSmi()) result = AssignEnvironment(result);
+ return result;
}
- return res;
}
} else if (from.IsDouble()) {
if (to.IsTagged()) {
info()->MarkAsDeferredCalling();
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister();
-
- // Make sure that the temp and result_temp registers are
- // different.
LUnallocated* result_temp = TempRegister();
LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2);
- Define(result, result_temp);
- return AssignPointerMap(result);
+ return AssignPointerMap(Define(result, result_temp));
} else if (to.IsSmi()) {
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
return AssignEnvironment(
DefineAsRegister(new(zone()) LDoubleToSmi(value)));
} else {
ASSERT(to.IsInteger32());
- LOperand* value = UseRegister(instr->value());
- LDoubleToI* res = new(zone()) LDoubleToI(value);
- return AssignEnvironment(DefineAsRegister(res));
+ LOperand* value = UseRegister(val);
+ LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value));
+ if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result);
+ return result;
}
} else if (from.IsInteger32()) {
info()->MarkAsDeferredCalling();
if (to.IsTagged()) {
- HValue* val = instr->value();
- LOperand* value = UseRegisterAtStart(val);
if (!instr->CheckFlag(HValue::kCanOverflow)) {
+ LOperand* value = UseRegisterAtStart(val);
return DefineAsRegister(new(zone()) LSmiTag(value));
} else if (val->CheckFlag(HInstruction::kUint32)) {
+ LOperand* value = UseRegisterAtStart(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister();
LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ return AssignPointerMap(DefineAsRegister(result));
} else {
+ LOperand* value = UseRegisterAtStart(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister();
LNumberTagI* result = new(zone()) LNumberTagI(value, temp1, temp2);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ return AssignPointerMap(DefineAsRegister(result));
}
} else if (to.IsSmi()) {
- HValue* val = instr->value();
LOperand* value = UseRegister(val);
LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
if (instr->CheckFlag(HValue::kCanOverflow)) {
@@ -1878,12 +1886,10 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
return result;
} else {
ASSERT(to.IsDouble());
- if (instr->value()->CheckFlag(HInstruction::kUint32)) {
- return DefineAsRegister(
- new(zone()) LUint32ToDouble(UseRegister(instr->value())));
+ if (val->CheckFlag(HInstruction::kUint32)) {
+ return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val)));
} else {
- return DefineAsRegister(
- new(zone()) LInteger32ToDouble(Use(instr->value())));
+ return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val)));
}
}
}
@@ -1894,7 +1900,9 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
LOperand* value = UseRegisterAtStart(instr->value());
- return AssignEnvironment(new(zone()) LCheckNonSmi(value));
+ LInstruction* result = new(zone()) LCheckNonSmi(value);
+ if (!instr->value()->IsHeapObject()) result = AssignEnvironment(result);
+ return result;
}
@@ -1918,15 +1926,12 @@ LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
- LOperand* value = NULL;
- if (!instr->CanOmitMapChecks()) {
- value = UseRegisterAtStart(instr->value());
- if (instr->has_migration_target()) info()->MarkAsDeferredCalling();
- }
- LCheckMaps* result = new(zone()) LCheckMaps(value);
- if (!instr->CanOmitMapChecks()) {
- AssignEnvironment(result);
- if (instr->has_migration_target()) return AssignPointerMap(result);
+ if (instr->IsStabilityCheck()) return new(zone()) LCheckMaps;
+ LOperand* value = UseRegisterAtStart(instr->value());
+ LInstruction* result = AssignEnvironment(new(zone()) LCheckMaps(value));
+ if (instr->HasMigrationTarget()) {
+ info()->MarkAsDeferredCalling();
+ result = AssignPointerMap(result);
}
return result;
}
@@ -2025,7 +2030,10 @@ LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
LOperand* context = UseRegisterAtStart(instr->value());
LInstruction* result =
DefineAsRegister(new(zone()) LLoadContextSlot(context));
- return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
+ if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -2040,7 +2048,10 @@ LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
value = UseRegister(instr->value());
}
LInstruction* result = new(zone()) LStoreContextSlot(context, value);
- return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
+ if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -2075,7 +2086,7 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
ASSERT(instr->key()->representation().IsSmiOrInteger32());
ElementsKind elements_kind = instr->elements_kind();
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
- LLoadKeyed* result = NULL;
+ LInstruction* result = NULL;
if (!instr->is_typed_elements()) {
LOperand* obj = NULL;
@@ -2085,24 +2096,28 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
ASSERT(instr->representation().IsSmiOrTagged());
obj = UseRegisterAtStart(instr->elements());
}
- result = new(zone()) LLoadKeyed(obj, key);
+ result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key));
} else {
ASSERT(
(instr->representation().IsInteger32() &&
- !IsDoubleOrFloatElementsKind(instr->elements_kind())) ||
+ !IsDoubleOrFloatElementsKind(elements_kind)) ||
(instr->representation().IsDouble() &&
- IsDoubleOrFloatElementsKind(instr->elements_kind())));
+ IsDoubleOrFloatElementsKind(elements_kind)));
LOperand* backing_store = UseRegister(instr->elements());
- result = new(zone()) LLoadKeyed(backing_store, key);
+ result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key));
}
- DefineAsRegister(result);
- // An unsigned int array load might overflow and cause a deopt, make sure it
- // has an environment.
- bool can_deoptimize = instr->RequiresHoleCheck() ||
- elements_kind == EXTERNAL_UINT32_ELEMENTS ||
- elements_kind == UINT32_ELEMENTS;
- return can_deoptimize ? AssignEnvironment(result) : result;
+ if ((instr->is_external() || instr->is_fixed_typed_array()) ?
+ // see LCodeGen::DoLoadKeyedExternalArray
+ ((elements_kind == EXTERNAL_UINT32_ELEMENTS ||
+ elements_kind == UINT32_ELEMENTS) &&
+ !instr->CheckFlag(HInstruction::kUint32)) :
+ // see LCodeGen::DoLoadKeyedFixedDoubleArray and
+ // LCodeGen::DoLoadKeyedFixedArray
+ instr->RequiresHoleCheck()) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -2178,17 +2193,18 @@ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- LOperand* object = UseRegister(instr->object());
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
+ LOperand* object = UseRegister(instr->object());
LOperand* new_map_reg = TempRegister();
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, NULL, new_map_reg);
return result;
} else {
+ LOperand* object = UseFixed(instr->object(), a0);
LOperand* context = UseFixed(instr->context(), cp);
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, context, NULL);
- return AssignPointerMap(result);
+ return MarkAsCall(result, instr);
}
}
@@ -2232,11 +2248,11 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
// We need a temporary register for write barrier of the map field.
LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;
- LStoreNamedField* result = new(zone()) LStoreNamedField(obj, val, temp);
- if (instr->field_representation().IsHeapObject()) {
- if (!instr->value()->type().IsHeapObject()) {
- return AssignEnvironment(result);
- }
+ LInstruction* result = new(zone()) LStoreNamedField(obj, val, temp);
+ if (!instr->access().IsExternalMemory() &&
+ instr->field_representation().IsHeapObject() &&
+ !instr->value()->type().IsHeapObject()) {
+ result = AssignEnvironment(result);
}
return result;
}
@@ -2268,7 +2284,7 @@ LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
LOperand* context = UseAny(instr->context());
LStringCharCodeAt* result =
new(zone()) LStringCharCodeAt(context, string, index);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ return AssignPointerMap(DefineAsRegister(result));
}
@@ -2324,7 +2340,7 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
} else {
ASSERT(info()->IsStub());
CodeStubInterfaceDescriptor* descriptor =
- info()->code_stub()->GetInterfaceDescriptor(info()->isolate());
+ info()->code_stub()->GetInterfaceDescriptor();
int index = static_cast<int>(instr->index());
Register reg = descriptor->GetParameterRegister(index);
return DefineFixed(result, reg);
@@ -2431,6 +2447,7 @@ LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
HEnvironment* outer = current_block_->last_environment();
+ outer->set_ast_id(instr->ReturnId());
HConstant* undefined = graph()->GetConstantUndefined();
HEnvironment* inner = outer->CopyForInlining(instr->closure(),
instr->arguments_count(),
@@ -2491,7 +2508,9 @@ LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
LOperand* object = UseRegister(instr->object());
LOperand* index = UseRegister(instr->index());
- return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index));
+ LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index);
+ LInstruction* result = DefineSameAsFirst(load);
+ return AssignPointerMap(result);
}
diff --git a/deps/v8/src/mips/lithium-mips.h b/deps/v8/src/mips/lithium-mips.h
index ae59e57f27..14ac0a4823 100644
--- a/deps/v8/src/mips/lithium-mips.h
+++ b/deps/v8/src/mips/lithium-mips.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_MIPS_LITHIUM_MIPS_H_
#define V8_MIPS_LITHIUM_MIPS_H_
@@ -97,6 +74,7 @@ class LCodeGen;
V(DummyUse) \
V(FlooringDivByConstI) \
V(FlooringDivByPowerOf2I) \
+ V(FlooringDivI) \
V(ForInCacheArray) \
V(ForInPrepareMap) \
V(FunctionLiteral) \
@@ -258,7 +236,9 @@ class LInstruction : public ZoneObject {
// Interface to the register allocator and iterators.
bool ClobbersTemps() const { return IsCall(); }
bool ClobbersRegisters() const { return IsCall(); }
- virtual bool ClobbersDoubleRegisters() const { return IsCall(); }
+ virtual bool ClobbersDoubleRegisters(Isolate* isolate) const {
+ return IsCall();
+ }
// Interface to the register allocator and iterators.
bool IsMarkedAsCall() const { return IsCall(); }
@@ -709,13 +689,13 @@ class LDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 0> {
class LDivI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public:
- LDivI(LOperand* left, LOperand* right) {
- inputs_[0] = left;
- inputs_[1] = right;
+ LDivI(LOperand* dividend, LOperand* divisor) {
+ inputs_[0] = dividend;
+ inputs_[1] = divisor;
}
- LOperand* left() { return inputs_[0]; }
- LOperand* right() { return inputs_[1]; }
+ LOperand* dividend() { return inputs_[0]; }
+ LOperand* divisor() { return inputs_[1]; }
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
@@ -761,6 +741,21 @@ class LFlooringDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 2> {
};
+class LFlooringDivI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+ LFlooringDivI(LOperand* dividend, LOperand* divisor) {
+ inputs_[0] = dividend;
+ inputs_[1] = divisor;
+ }
+
+ LOperand* dividend() { return inputs_[0]; }
+ LOperand* divisor() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i")
+ DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+};
+
+
class LMulI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public:
LMulI(LOperand* left, LOperand* right) {
@@ -1931,7 +1926,7 @@ class LCallRuntime V8_FINAL : public LTemplateInstruction<1, 1, 0> {
DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
- virtual bool ClobbersDoubleRegisters() const V8_OVERRIDE {
+ virtual bool ClobbersDoubleRegisters(Isolate* isolate) const V8_OVERRIDE {
return save_doubles() == kDontSaveFPRegs;
}
@@ -2127,7 +2122,6 @@ class LStoreNamedField V8_FINAL : public LTemplateInstruction<0, 2, 1> {
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
- Handle<Map> transition() const { return hydrogen()->transition_map(); }
Representation representation() const {
return hydrogen()->field_representation();
}
@@ -2336,7 +2330,7 @@ class LCheckInstanceType V8_FINAL : public LTemplateInstruction<0, 1, 0> {
class LCheckMaps V8_FINAL : public LTemplateInstruction<0, 1, 0> {
public:
- explicit LCheckMaps(LOperand* value) {
+ explicit LCheckMaps(LOperand* value = NULL) {
inputs_[0] = value;
}
@@ -2655,6 +2649,8 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
next_block_(NULL),
allocator_(allocator) { }
+ Isolate* isolate() const { return graph_->isolate(); }
+
// Build the sequence for the graph.
LPlatformChunk* Build();
@@ -2679,12 +2675,13 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
LInstruction* DoMathClz32(HUnaryMathOperation* instr);
LInstruction* DoDivByPowerOf2I(HDiv* instr);
LInstruction* DoDivByConstI(HDiv* instr);
- LInstruction* DoDivI(HBinaryOperation* instr);
+ LInstruction* DoDivI(HDiv* instr);
LInstruction* DoModByPowerOf2I(HMod* instr);
LInstruction* DoModByConstI(HMod* instr);
LInstruction* DoModI(HMod* instr);
LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr);
LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr);
+ LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr);
private:
enum Status {
diff --git a/deps/v8/src/mips/macro-assembler-mips.cc b/deps/v8/src/mips/macro-assembler-mips.cc
index 77c02e7342..9291e20fa6 100644
--- a/deps/v8/src/mips/macro-assembler-mips.cc
+++ b/deps/v8/src/mips/macro-assembler-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <limits.h> // For LONG_MIN, LONG_MAX.
@@ -302,7 +279,8 @@ void MacroAssembler::RecordWrite(Register object,
if (ra_status == kRAHasNotBeenSaved) {
push(ra);
}
- RecordWriteStub stub(object, value, address, remembered_set_action, fp_mode);
+ RecordWriteStub stub(isolate(), object, value, address, remembered_set_action,
+ fp_mode);
CallStub(&stub);
if (ra_status == kRAHasNotBeenSaved) {
pop(ra);
@@ -352,7 +330,7 @@ void MacroAssembler::RememberedSetHelper(Register object, // For debug tests.
}
push(ra);
StoreBufferOverflowStub store_buffer_overflow =
- StoreBufferOverflowStub(fp_mode);
+ StoreBufferOverflowStub(isolate(), fp_mode);
CallStub(&store_buffer_overflow);
pop(ra);
bind(&done);
@@ -1456,7 +1434,7 @@ void MacroAssembler::TruncateDoubleToI(Register result,
Subu(sp, sp, Operand(kDoubleSize)); // Put input on stack.
sdc1(double_input, MemOperand(sp, 0));
- DoubleToIStub stub(sp, result, 0, true, true);
+ DoubleToIStub stub(isolate(), sp, result, 0, true, true);
CallStub(&stub);
Addu(sp, sp, Operand(kDoubleSize));
@@ -1477,7 +1455,8 @@ void MacroAssembler::TruncateHeapNumberToI(Register result, Register object) {
// If we fell through then inline version didn't succeed - call stub instead.
push(ra);
- DoubleToIStub stub(object,
+ DoubleToIStub stub(isolate(),
+ object,
result,
HeapNumber::kValueOffset - kHeapObjectTag,
true,
@@ -2091,7 +2070,7 @@ void MacroAssembler::BranchShort(Label* L, Condition cond, Register rs,
case Uless_equal:
if (rt.imm32_ == 0) {
offset = shifted_branch_offset(L, false);
- b(offset);
+ beq(rs, zero_reg, offset);
} else {
ASSERT(!scratch.is(rs));
r2 = scratch;
@@ -2686,18 +2665,14 @@ void MacroAssembler::Push(Handle<Object> handle) {
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
-
void MacroAssembler::DebugBreak() {
PrepareCEntryArgs(0);
PrepareCEntryFunction(ExternalReference(Runtime::kDebugBreak, isolate()));
- CEntryStub ces(1);
+ CEntryStub ces(isolate(), 1);
ASSERT(AllowThisStubCall(&ces));
- Call(ces.GetCode(isolate()), RelocInfo::DEBUG_BREAK);
+ Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
}
-#endif // ENABLE_DEBUGGER_SUPPORT
-
// ---------------------------------------------------------------------------
// Exception handling.
@@ -3313,13 +3288,24 @@ void MacroAssembler::CopyBytes(Register src,
// TODO(kalmard) check if this can be optimized to use sw in most cases.
// Can't use unaligned access - copy byte by byte.
- sb(scratch, MemOperand(dst, 0));
- srl(scratch, scratch, 8);
- sb(scratch, MemOperand(dst, 1));
- srl(scratch, scratch, 8);
- sb(scratch, MemOperand(dst, 2));
- srl(scratch, scratch, 8);
- sb(scratch, MemOperand(dst, 3));
+ if (kArchEndian == kLittle) {
+ sb(scratch, MemOperand(dst, 0));
+ srl(scratch, scratch, 8);
+ sb(scratch, MemOperand(dst, 1));
+ srl(scratch, scratch, 8);
+ sb(scratch, MemOperand(dst, 2));
+ srl(scratch, scratch, 8);
+ sb(scratch, MemOperand(dst, 3));
+ } else {
+ sb(scratch, MemOperand(dst, 3));
+ srl(scratch, scratch, 8);
+ sb(scratch, MemOperand(dst, 2));
+ srl(scratch, scratch, 8);
+ sb(scratch, MemOperand(dst, 1));
+ srl(scratch, scratch, 8);
+ sb(scratch, MemOperand(dst, 0));
+ }
+
Addu(dst, dst, 4);
Subu(length, length, Operand(kPointerSize));
@@ -3424,11 +3410,12 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
bind(&have_double_value);
sll(scratch1, key_reg, kDoubleSizeLog2 - kSmiTagSize);
Addu(scratch1, scratch1, elements_reg);
- sw(mantissa_reg, FieldMemOperand(
- scratch1, FixedDoubleArray::kHeaderSize - elements_offset));
- uint32_t offset = FixedDoubleArray::kHeaderSize - elements_offset +
- sizeof(kHoleNanLower32);
- sw(exponent_reg, FieldMemOperand(scratch1, offset));
+ sw(mantissa_reg,
+ FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - elements_offset
+ + kHoleNanLower32Offset));
+ sw(exponent_reg,
+ FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - elements_offset
+ + kHoleNanUpper32Offset));
jmp(&done);
bind(&maybe_nan);
@@ -3526,7 +3513,11 @@ void MacroAssembler::CheckMap(Register obj,
void MacroAssembler::MovFromFloatResult(DoubleRegister dst) {
if (IsMipsSoftFloatABI) {
- Move(dst, v0, v1);
+ if (kArchEndian == kLittle) {
+ Move(dst, v0, v1);
+ } else {
+ Move(dst, v1, v0);
+ }
} else {
Move(dst, f0); // Reg f0 is o32 ABI FP return value.
}
@@ -3535,7 +3526,11 @@ void MacroAssembler::MovFromFloatResult(DoubleRegister dst) {
void MacroAssembler::MovFromFloatParameter(DoubleRegister dst) {
if (IsMipsSoftFloatABI) {
- Move(dst, a0, a1);
+ if (kArchEndian == kLittle) {
+ Move(dst, a0, a1);
+ } else {
+ Move(dst, a1, a0);
+ }
} else {
Move(dst, f12); // Reg f12 is o32 ABI FP first argument value.
}
@@ -3546,7 +3541,11 @@ void MacroAssembler::MovToFloatParameter(DoubleRegister src) {
if (!IsMipsSoftFloatABI) {
Move(f12, src);
} else {
- Move(a0, a1, src);
+ if (kArchEndian == kLittle) {
+ Move(a0, a1, src);
+ } else {
+ Move(a1, a0, src);
+ }
}
}
@@ -3555,7 +3554,11 @@ void MacroAssembler::MovToFloatResult(DoubleRegister src) {
if (!IsMipsSoftFloatABI) {
Move(f0, src);
} else {
- Move(v0, v1, src);
+ if (kArchEndian == kLittle) {
+ Move(v0, v1, src);
+ } else {
+ Move(v1, v0, src);
+ }
}
}
@@ -3572,8 +3575,13 @@ void MacroAssembler::MovToFloatParameters(DoubleRegister src1,
Move(f14, src2);
}
} else {
- Move(a0, a1, src1);
- Move(a2, a3, src2);
+ if (kArchEndian == kLittle) {
+ Move(a0, a1, src1);
+ Move(a2, a3, src2);
+ } else {
+ Move(a1, a0, src1);
+ Move(a3, a2, src2);
+ }
}
}
@@ -3859,7 +3867,7 @@ void MacroAssembler::CallStub(CodeStub* stub,
const Operand& r2,
BranchDelaySlot bd) {
ASSERT(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs.
- Call(stub->GetCode(isolate()), RelocInfo::CODE_TARGET, ast_id,
+ Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id,
cond, r1, r2, bd);
}
@@ -3869,7 +3877,7 @@ void MacroAssembler::TailCallStub(CodeStub* stub,
Register r1,
const Operand& r2,
BranchDelaySlot bd) {
- Jump(stub->GetCode(isolate()), RelocInfo::CODE_TARGET, cond, r1, r2, bd);
+ Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond, r1, r2, bd);
}
@@ -3898,10 +3906,7 @@ void MacroAssembler::CallApiFunctionAndReturn(
Label profiler_disabled;
Label end_profiler_check;
- bool* is_profiling_flag =
- isolate()->cpu_profiler()->is_profiling_address();
- STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
- li(t9, reinterpret_cast<int32_t>(is_profiling_flag));
+ li(t9, Operand(ExternalReference::is_profiling_address(isolate())));
lb(t9, MemOperand(t9, 0));
Branch(&profiler_disabled, eq, t9, Operand(zero_reg));
@@ -3933,7 +3938,7 @@ void MacroAssembler::CallApiFunctionAndReturn(
// Native call returns to the DirectCEntry stub which redirects to the
// return address pushed on stack (could have moved after GC).
// DirectCEntry stub itself is generated early and never moves.
- DirectCEntryStub stub;
+ DirectCEntryStub stub(isolate());
stub.GenerateCall(this, t9);
if (FLAG_log_timer_events) {
@@ -4010,14 +4015,6 @@ bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
}
-void MacroAssembler::IllegalOperation(int num_arguments) {
- if (num_arguments > 0) {
- addiu(sp, sp, num_arguments * kPointerSize);
- }
- LoadRoot(v0, Heap::kUndefinedValueRootIndex);
-}
-
-
void MacroAssembler::IndexFromHash(Register hash,
Register index) {
// If the hash field contains an array index pick it out. The assert checks
@@ -4172,10 +4169,7 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f,
// If the expected number of arguments of the runtime function is
// constant, we check that the actual number of arguments match the
// expectation.
- if (f->nargs >= 0 && f->nargs != num_arguments) {
- IllegalOperation(num_arguments);
- return;
- }
+ CHECK(f->nargs < 0 || f->nargs == num_arguments);
// TODO(1236192): Most runtime routines don't need the number of
// arguments passed in because it is constant. At some point we
@@ -4183,7 +4177,7 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f,
// smarter.
PrepareCEntryArgs(num_arguments);
PrepareCEntryFunction(ExternalReference(f, isolate()));
- CEntryStub stub(1, save_doubles);
+ CEntryStub stub(isolate(), 1, save_doubles);
CallStub(&stub);
}
@@ -4194,7 +4188,7 @@ void MacroAssembler::CallExternalReference(const ExternalReference& ext,
PrepareCEntryArgs(num_arguments);
PrepareCEntryFunction(ext);
- CEntryStub stub(1);
+ CEntryStub stub(isolate(), 1);
CallStub(&stub, TypeFeedbackId::None(), al, zero_reg, Operand(zero_reg), bd);
}
@@ -4223,8 +4217,8 @@ void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid,
void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin,
BranchDelaySlot bd) {
PrepareCEntryFunction(builtin);
- CEntryStub stub(1);
- Jump(stub.GetCode(isolate()),
+ CEntryStub stub(isolate(), 1);
+ Jump(stub.GetCode(),
RelocInfo::CODE_TARGET,
al,
zero_reg,
@@ -4466,7 +4460,7 @@ void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
Addu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
} else {
PredictableCodeSizeScope predictible_code_size_scope(
- this, kNoCodeAgeSequenceLength * Assembler::kInstrSize);
+ this, kNoCodeAgeSequenceLength);
// The following three instructions must remain together and unmodified
// for code aging to work properly.
if (isolate()->IsCodePreAgingActive()) {
@@ -5670,10 +5664,13 @@ bool AreAliased(Register r1, Register r2, Register r3, Register r4) {
}
-CodePatcher::CodePatcher(byte* address, int instructions)
+CodePatcher::CodePatcher(byte* address,
+ int instructions,
+ FlushICache flush_cache)
: address_(address),
size_(instructions * Assembler::kInstrSize),
- masm_(NULL, address, size_ + Assembler::kGap) {
+ masm_(NULL, address, size_ + Assembler::kGap),
+ flush_cache_(flush_cache) {
// Create a new macro assembler pointing to the address of the code to patch.
// The size is adjusted with kGap on order for the assembler to generate size
// bytes of instructions without failing with buffer size constraints.
@@ -5683,7 +5680,9 @@ CodePatcher::CodePatcher(byte* address, int instructions)
CodePatcher::~CodePatcher() {
// Indicate that code has changed.
- CPU::FlushICache(address_, size_);
+ if (flush_cache_ == FLUSH) {
+ CPU::FlushICache(address_, size_);
+ }
// Check that the code was patched as expected.
ASSERT(masm_.pc_ == address_ + size_);
diff --git a/deps/v8/src/mips/macro-assembler-mips.h b/deps/v8/src/mips/macro-assembler-mips.h
index db9f1a2c76..774449cab8 100644
--- a/deps/v8/src/mips/macro-assembler-mips.h
+++ b/deps/v8/src/mips/macro-assembler-mips.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_MIPS_MACRO_ASSEMBLER_MIPS_H_
#define V8_MIPS_MACRO_ASSEMBLER_MIPS_H_
@@ -932,13 +909,10 @@ class MacroAssembler: public Assembler {
Register scratch,
Label* fail);
-#ifdef ENABLE_DEBUGGER_SUPPORT
// -------------------------------------------------------------------------
// Debugger Support.
void DebugBreak();
-#endif
-
// -------------------------------------------------------------------------
// Exception handling.
@@ -1074,10 +1048,6 @@ class MacroAssembler: public Assembler {
Handle<Code> success,
SmiCheckType smi_check_type);
- // Generates code for reporting that an illegal operation has
- // occurred.
- void IllegalOperation(int num_arguments);
-
// Load and check the instance type of an object for being a string.
// Loads the type into the second argument register.
@@ -1644,7 +1614,14 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
// an assertion to fail.
class CodePatcher {
public:
- CodePatcher(byte* address, int instructions);
+ enum FlushICache {
+ FLUSH,
+ DONT_FLUSH
+ };
+
+ CodePatcher(byte* address,
+ int instructions,
+ FlushICache flush_cache = FLUSH);
virtual ~CodePatcher();
// Macro assembler to emit code.
@@ -1664,6 +1641,7 @@ class CodePatcher {
byte* address_; // The address of the code being patched.
int size_; // Number of bytes of the expected patch size.
MacroAssembler masm_; // Macro assembler used to generate the code.
+ FlushICache flush_cache_; // Whether to flush the I cache after patching.
};
diff --git a/deps/v8/src/mips/regexp-macro-assembler-mips.cc b/deps/v8/src/mips/regexp-macro-assembler-mips.cc
index 49dec3c024..7c8fde900f 100644
--- a/deps/v8/src/mips/regexp-macro-assembler-mips.cc
+++ b/deps/v8/src/mips/regexp-macro-assembler-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -1096,7 +1073,7 @@ void RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) {
ExternalReference stack_guard_check =
ExternalReference::re_check_stack_guard_state(masm_->isolate());
__ li(t9, Operand(stack_guard_check));
- DirectCEntryStub stub;
+ DirectCEntryStub stub(isolate());
stub.GenerateCall(masm_, t9);
// DirectCEntryStub allocated space for the C argument slots so we have to
@@ -1153,7 +1130,7 @@ int RegExpMacroAssemblerMIPS::CheckStackGuardState(Address* return_address,
ASSERT(*return_address <=
re_code->instruction_start() + re_code->instruction_size());
- MaybeObject* result = Execution::HandleStackGuardInterrupt(isolate);
+ Object* result = Execution::HandleStackGuardInterrupt(isolate);
if (*code_handle != re_code) { // Return address no longer valid.
int delta = code_handle->address() - re_code->address();
diff --git a/deps/v8/src/mips/regexp-macro-assembler-mips.h b/deps/v8/src/mips/regexp-macro-assembler-mips.h
index 063582c648..f0aba07dc2 100644
--- a/deps/v8/src/mips/regexp-macro-assembler-mips.h
+++ b/deps/v8/src/mips/regexp-macro-assembler-mips.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_MIPS_REGEXP_MACRO_ASSEMBLER_MIPS_H_
diff --git a/deps/v8/src/mips/simulator-mips.cc b/deps/v8/src/mips/simulator-mips.cc
index d26499bbc5..51f679bdc1 100644
--- a/deps/v8/src/mips/simulator-mips.cc
+++ b/deps/v8/src/mips/simulator-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <limits.h>
#include <stdarg.h>
diff --git a/deps/v8/src/mips/simulator-mips.h b/deps/v8/src/mips/simulator-mips.h
index 92a0a87d24..feeb7bcfc1 100644
--- a/deps/v8/src/mips/simulator-mips.h
+++ b/deps/v8/src/mips/simulator-mips.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Declares a Simulator for MIPS instructions if we are not generating a native
diff --git a/deps/v8/src/mips/stub-cache-mips.cc b/deps/v8/src/mips/stub-cache-mips.cc
index 153a816820..abccc9496b 100644
--- a/deps/v8/src/mips/stub-cache-mips.cc
+++ b/deps/v8/src/mips/stub-cache-mips.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -416,6 +393,24 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
__ JumpIfSmi(value_reg, miss_label);
+ HeapType* field_type = descriptors->GetFieldType(descriptor);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ Handle<Map> current;
+ if (!it.Done()) {
+ __ lw(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ while (true) {
+ // Do the CompareMap() directly within the Branch() functions.
+ current = it.Current();
+ it.Advance();
+ if (it.Done()) {
+ __ Branch(miss_label, ne, scratch1, Operand(current));
+ break;
+ }
+ __ Branch(&do_store, eq, scratch1, Operand(current));
+ }
+ __ bind(&do_store);
+ }
} else if (representation.IsDouble()) {
Label do_store, heap_number;
__ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex);
@@ -579,6 +574,24 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
__ JumpIfSmi(value_reg, miss_label);
+ HeapType* field_type = lookup->GetFieldType();
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ __ lw(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ Handle<Map> current;
+ while (true) {
+ // Do the CompareMap() directly within the Branch() functions.
+ current = it.Current();
+ it.Advance();
+ if (it.Done()) {
+ __ Branch(miss_label, ne, scratch1, Operand(current));
+ break;
+ }
+ __ Branch(&do_store, eq, scratch1, Operand(current));
+ }
+ __ bind(&do_store);
+ }
} else if (representation.IsDouble()) {
// Load the double storage.
if (index < 0) {
@@ -789,7 +802,7 @@ void StubCompiler::GenerateFastApiCall(MacroAssembler* masm,
__ li(api_function_address, Operand(ref));
// Jump to stub.
- CallApiFunctionStub stub(is_store, call_data_undefined, argc);
+ CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
__ TailCallStub(&stub);
}
@@ -824,7 +837,9 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
int depth = 0;
Handle<JSObject> current = Handle<JSObject>::null();
- if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant());
+ if (type->IsConstant()) {
+ current = Handle<JSObject>::cast(type->AsConstant()->Value());
+ }
Handle<JSObject> prototype = Handle<JSObject>::null();
Handle<Map> current_map = receiver_map;
Handle<Map> holder_map(holder->map());
@@ -847,7 +862,7 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
name = factory()->InternalizeString(Handle<String>::cast(name));
}
ASSERT(current.is_null() ||
- current->property_dictionary()->FindEntry(*name) ==
+ current->property_dictionary()->FindEntry(name) ==
NameDictionary::kNotFound);
GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
@@ -986,15 +1001,17 @@ void LoadStubCompiler::GenerateLoadField(Register reg,
Representation representation) {
if (!reg.is(receiver())) __ mov(receiver(), reg);
if (kind() == Code::LOAD_IC) {
- LoadFieldStub stub(field.is_inobject(holder),
+ LoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
field.translate(holder),
representation);
- GenerateTailCall(masm(), stub.GetCode(isolate()));
+ GenerateTailCall(masm(), stub.GetCode());
} else {
- KeyedLoadFieldStub stub(field.is_inobject(holder),
+ KeyedLoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
field.translate(holder),
representation);
- GenerateTailCall(masm(), stub.GetCode(isolate()));
+ GenerateTailCall(masm(), stub.GetCode());
}
}
@@ -1051,7 +1068,7 @@ void LoadStubCompiler::GenerateLoadCallback(
ExternalReference ref = ExternalReference(&fun, type, isolate());
__ li(getter_address_reg, Operand(ref));
- CallApiGetterStub stub;
+ CallApiGetterStub stub(isolate());
__ TailCallStub(&stub);
}
@@ -1141,17 +1158,6 @@ void LoadStubCompiler::GenerateLoadInterceptor(
}
-void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
- Label success;
- // Check that the object is a boolean.
- __ LoadRoot(at, Heap::kTrueValueRootIndex);
- __ Branch(&success, eq, object, Operand(at));
- __ LoadRoot(at, Heap::kFalseValueRootIndex);
- __ Branch(miss, ne, object, Operand(at));
- __ bind(&success);
-}
-
-
Handle<Code> StoreStubCompiler::CompileStoreCallback(
Handle<JSObject> object,
Handle<JSObject> holder,
diff --git a/deps/v8/src/mirror-debugger.js b/deps/v8/src/mirror-debugger.js
index d413b090b7..fde3f10f3f 100644
--- a/deps/v8/src/mirror-debugger.js
+++ b/deps/v8/src/mirror-debugger.js
@@ -1,29 +1,6 @@
// Copyright 2006-2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Handle id counters.
var next_handle_ = 0;
@@ -42,6 +19,18 @@ function ClearMirrorCache() {
}
+// Wrapper to check whether an object is a Promise. The call may not work
+// if promises are not enabled.
+// TODO(yangguo): remove this wrapper once promises are enabled by default.
+function ObjectIsPromise(value) {
+ try {
+ return %IsPromise(value);
+ } catch (e) {
+ return false;
+ }
+}
+
+
/**
* Returns the mirror for a specified value or object.
*
@@ -90,6 +79,8 @@ function MakeMirror(value, opt_transient) {
mirror = new ErrorMirror(value);
} else if (IS_SCRIPT(value)) {
mirror = new ScriptMirror(value);
+ } else if (ObjectIsPromise(value)) {
+ mirror = new PromiseMirror(value);
} else {
mirror = new ObjectMirror(value, OBJECT_TYPE, opt_transient);
}
@@ -159,6 +150,7 @@ var FRAME_TYPE = 'frame';
var SCRIPT_TYPE = 'script';
var CONTEXT_TYPE = 'context';
var SCOPE_TYPE = 'scope';
+var PROMISE_TYPE = 'promise';
// Maximum length when sending strings through the JSON protocol.
var kMaxProtocolStringLength = 80;
@@ -212,6 +204,7 @@ var ScopeType = { Global: 0,
// - DateMirror
// - RegExpMirror
// - ErrorMirror
+// - PromiseMirror
// - PropertyMirror
// - InternalPropertyMirror
// - FrameMirror
@@ -351,6 +344,15 @@ Mirror.prototype.isError = function() {
/**
+ * Check whether the mirror reflects a promise.
+ * @returns {boolean} True if the mirror reflects a promise
+ */
+Mirror.prototype.isPromise = function() {
+ return this instanceof PromiseMirror;
+};
+
+
+/**
* Check whether the mirror reflects a property.
* @returns {boolean} True if the mirror reflects a property
*/
@@ -637,9 +639,9 @@ ObjectMirror.prototype.propertyNames = function(kind, limit) {
// Find all the named properties.
if (kind & PropertyKind.Named) {
- // Get all the local property names.
+ // Get all the local property names except for private symbols.
propertyNames =
- %GetLocalPropertyNames(this.value_, PROPERTY_ATTRIBUTES_NONE);
+ %GetLocalPropertyNames(this.value_, PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL);
total += propertyNames.length;
// Get names for named interceptor properties if any.
@@ -1172,6 +1174,31 @@ ErrorMirror.prototype.toText = function() {
/**
+ * Mirror object for a Promise object.
+ * @param {Object} data The Promise object
+ * @constructor
+ * @extends Mirror
+ */
+function PromiseMirror(value) {
+ %_CallFunction(this, value, PROMISE_TYPE, ObjectMirror);
+}
+inherits(PromiseMirror, ObjectMirror);
+
+
+PromiseMirror.prototype.status = function() {
+ var status = builtins.GetPromiseStatus(this.value_);
+ if (status == 0) return "pending";
+ if (status == 1) return "resolved";
+ return "rejected";
+};
+
+
+PromiseMirror.prototype.promiseValue = function() {
+ return builtins.GetPromiseValue(this.value_);
+};
+
+
+/**
* Base mirror object for properties.
* @param {ObjectMirror} mirror The mirror object having this property
* @param {string} name The name of the property
@@ -2350,6 +2377,7 @@ JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference,
case FUNCTION_TYPE:
case ERROR_TYPE:
case REGEXP_TYPE:
+ case PROMISE_TYPE:
// Add object representation.
this.serializeObject_(mirror, content, details);
break;
@@ -2452,7 +2480,6 @@ JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content,
content.indexedInterceptor = true;
}
- // Add function specific properties.
if (mirror.isFunction()) {
// Add function specific properties.
content.name = mirror.name();
@@ -2480,12 +2507,17 @@ JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content,
}
}
- // Add date specific properties.
if (mirror.isDate()) {
// Add date specific properties.
content.value = mirror.value();
}
+ if (mirror.isPromise()) {
+ // Add promise specific properties.
+ content.status = mirror.status();
+ content.promiseValue = mirror.promiseValue();
+ }
+
// Add actual properties - named properties followed by indexed properties.
var propertyNames = mirror.propertyNames(PropertyKind.Named);
var propertyIndexes = mirror.propertyNames(PropertyKind.Indexed);
diff --git a/deps/v8/src/misc-intrinsics.h b/deps/v8/src/misc-intrinsics.h
index 5393de2c21..a8582bbe11 100644
--- a/deps/v8/src/misc-intrinsics.h
+++ b/deps/v8/src/misc-intrinsics.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_MISC_INTRINSICS_H_
#define V8_MISC_INTRINSICS_H_
diff --git a/deps/v8/src/mksnapshot.cc b/deps/v8/src/mksnapshot.cc
index 07b0575492..a8bf871f13 100644
--- a/deps/v8/src/mksnapshot.cc
+++ b/deps/v8/src/mksnapshot.cc
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <errno.h>
#include <stdio.h>
@@ -41,6 +18,10 @@
#include "serialize.h"
#include "list.h"
+#if V8_TARGET_ARCH_ARM
+#include "arm/assembler-arm-inl.h"
+#endif
+
using namespace v8;
@@ -52,148 +33,173 @@ class Compressor {
};
-class PartialSnapshotSink : public i::SnapshotByteSink {
+class ListSnapshotSink : public i::SnapshotByteSink {
+ public:
+ explicit ListSnapshotSink(i::List<char>* data) : data_(data) { }
+ virtual ~ListSnapshotSink() {}
+ virtual void Put(int byte, const char* description) { data_->Add(byte); }
+ virtual int Position() { return data_->length(); }
+ private:
+ i::List<char>* data_;
+};
+
+
+class SnapshotWriter {
public:
- PartialSnapshotSink() : data_(), raw_size_(-1) { }
- virtual ~PartialSnapshotSink() { data_.Free(); }
- virtual void Put(int byte, const char* description) {
- data_.Add(byte);
+ explicit SnapshotWriter(const char* snapshot_file)
+ : fp_(GetFileDescriptorOrDie(snapshot_file))
+ , raw_file_(NULL)
+ , raw_context_file_(NULL)
+ , compressor_(NULL)
+ , omit_(false) {
}
- virtual int Position() { return data_.length(); }
- void Print(FILE* fp) {
- int length = Position();
- for (int j = 0; j < length; j++) {
- if ((j & 0x1f) == 0x1f) {
- fprintf(fp, "\n");
- }
- if (j != 0) {
- fprintf(fp, ",");
- }
- fprintf(fp, "%u", static_cast<unsigned char>(at(j)));
- }
+
+ ~SnapshotWriter() {
+ fclose(fp_);
+ if (raw_file_) fclose(raw_file_);
+ if (raw_context_file_) fclose(raw_context_file_);
}
- char at(int i) { return data_[i]; }
- bool Compress(Compressor* compressor) {
- ASSERT_EQ(-1, raw_size_);
- raw_size_ = data_.length();
- if (!compressor->Compress(data_.ToVector())) return false;
- data_.Clear();
- data_.AddAll(*compressor->output());
- return true;
+
+ void SetCompressor(Compressor* compressor) {
+ compressor_ = compressor;
}
- int raw_size() { return raw_size_; }
- private:
- i::List<char> data_;
- int raw_size_;
-};
+ void SetOmit(bool omit) {
+ omit_ = omit;
+ }
+ void SetRawFiles(const char* raw_file, const char* raw_context_file) {
+ raw_file_ = GetFileDescriptorOrDie(raw_file);
+ raw_context_file_ = GetFileDescriptorOrDie(raw_context_file);
+ }
-class CppByteSink : public PartialSnapshotSink {
- public:
- explicit CppByteSink(const char* snapshot_file) {
- fp_ = i::OS::FOpen(snapshot_file, "wb");
- if (fp_ == NULL) {
- i::PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file);
- exit(1);
- }
+ void WriteSnapshot(const i::List<char>& snapshot_data,
+ const i::Serializer& serializer,
+ const i::List<char>& context_snapshot_data,
+ const i::Serializer& context_serializer) const {
+ WriteFilePrefix();
+ WriteData("", snapshot_data, raw_file_);
+ WriteData("context_", context_snapshot_data, raw_context_file_);
+ WriteMeta("context_", context_serializer);
+ WriteMeta("", serializer);
+ WriteFileSuffix();
+ }
+
+ private:
+ void WriteFilePrefix() const {
fprintf(fp_, "// Autogenerated snapshot file. Do not edit.\n\n");
fprintf(fp_, "#include \"v8.h\"\n");
fprintf(fp_, "#include \"platform.h\"\n\n");
fprintf(fp_, "#include \"snapshot.h\"\n\n");
- fprintf(fp_, "namespace v8 {\nnamespace internal {\n\n");
- fprintf(fp_, "const byte Snapshot::data_[] = {");
+ fprintf(fp_, "namespace v8 {\n");
+ fprintf(fp_, "namespace internal {\n\n");
}
- virtual ~CppByteSink() {
- fprintf(fp_, "const int Snapshot::size_ = %d;\n", Position());
-#ifdef COMPRESS_STARTUP_DATA_BZ2
- fprintf(fp_, "const byte* Snapshot::raw_data_ = NULL;\n");
- fprintf(fp_,
- "const int Snapshot::raw_size_ = %d;\n\n",
- raw_size());
-#else
- fprintf(fp_,
- "const byte* Snapshot::raw_data_ = Snapshot::data_;\n");
- fprintf(fp_,
- "const int Snapshot::raw_size_ = Snapshot::size_;\n\n");
-#endif
- fprintf(fp_, "} } // namespace v8::internal\n");
- fclose(fp_);
+ void WriteFileSuffix() const {
+ fprintf(fp_, "} // namespace internal\n");
+ fprintf(fp_, "} // namespace v8\n");
+ }
+
+ void WriteData(const char* prefix,
+ const i::List<char>& source_data,
+ FILE* raw_file) const {
+ const i::List <char>* data_to_be_written = NULL;
+ i::List<char> compressed_data;
+ if (!compressor_) {
+ data_to_be_written = &source_data;
+ } else if (compressor_->Compress(source_data.ToVector())) {
+ compressed_data.AddAll(*compressor_->output());
+ data_to_be_written = &compressed_data;
+ } else {
+ i::PrintF("Compression failed. Aborting.\n");
+ exit(1);
+ }
+
+ ASSERT(data_to_be_written);
+ MaybeWriteRawFile(data_to_be_written, raw_file);
+ WriteData(prefix, source_data, data_to_be_written);
}
- void WriteSpaceUsed(
- const char* prefix,
- int new_space_used,
- int pointer_space_used,
- int data_space_used,
- int code_space_used,
- int map_space_used,
- int cell_space_used,
- int property_cell_space_used) {
- fprintf(fp_,
- "const int Snapshot::%snew_space_used_ = %d;\n",
- prefix,
- new_space_used);
- fprintf(fp_,
- "const int Snapshot::%spointer_space_used_ = %d;\n",
- prefix,
- pointer_space_used);
- fprintf(fp_,
- "const int Snapshot::%sdata_space_used_ = %d;\n",
- prefix,
- data_space_used);
- fprintf(fp_,
- "const int Snapshot::%scode_space_used_ = %d;\n",
- prefix,
- code_space_used);
- fprintf(fp_,
- "const int Snapshot::%smap_space_used_ = %d;\n",
- prefix,
- map_space_used);
- fprintf(fp_,
- "const int Snapshot::%scell_space_used_ = %d;\n",
- prefix,
- cell_space_used);
- fprintf(fp_,
- "const int Snapshot::%sproperty_cell_space_used_ = %d;\n",
- prefix,
- property_cell_space_used);
+ void MaybeWriteRawFile(const i::List<char>* data, FILE* raw_file) const {
+ if (!data || !raw_file)
+ return;
+
+ // Sanity check, whether i::List iterators truly return pointers to an
+ // internal array.
+ ASSERT(data->end() - data->begin() == data->length());
+
+ size_t written = fwrite(data->begin(), 1, data->length(), raw_file);
+ if (written != (size_t)data->length()) {
+ i::PrintF("Writing raw file failed.. Aborting.\n");
+ exit(1);
+ }
}
- void WritePartialSnapshot() {
- int length = partial_sink_.Position();
- fprintf(fp_, "};\n\n");
- fprintf(fp_, "const int Snapshot::context_size_ = %d;\n", length);
-#ifdef COMPRESS_STARTUP_DATA_BZ2
- fprintf(fp_,
- "const int Snapshot::context_raw_size_ = %d;\n",
- partial_sink_.raw_size());
-#else
- fprintf(fp_,
- "const int Snapshot::context_raw_size_ = "
- "Snapshot::context_size_;\n");
-#endif
- fprintf(fp_, "const byte Snapshot::context_data_[] = {\n");
- partial_sink_.Print(fp_);
- fprintf(fp_, "};\n\n");
-#ifdef COMPRESS_STARTUP_DATA_BZ2
- fprintf(fp_, "const byte* Snapshot::context_raw_data_ = NULL;\n");
-#else
- fprintf(fp_, "const byte* Snapshot::context_raw_data_ ="
- " Snapshot::context_data_;\n");
-#endif
+ void WriteData(const char* prefix,
+ const i::List<char>& source_data,
+ const i::List<char>* data_to_be_written) const {
+ fprintf(fp_, "const byte Snapshot::%sdata_[] = {\n", prefix);
+ if (!omit_)
+ WriteSnapshotData(data_to_be_written);
+ fprintf(fp_, "};\n");
+ fprintf(fp_, "const int Snapshot::%ssize_ = %d;\n", prefix,
+ data_to_be_written->length());
+
+ if (data_to_be_written == &source_data && !omit_) {
+ fprintf(fp_, "const byte* Snapshot::%sraw_data_ = Snapshot::%sdata_;\n",
+ prefix, prefix);
+ fprintf(fp_, "const int Snapshot::%sraw_size_ = Snapshot::%ssize_;\n",
+ prefix, prefix);
+ } else {
+ fprintf(fp_, "const byte* Snapshot::%sraw_data_ = NULL;\n", prefix);
+ fprintf(fp_, "const int Snapshot::%sraw_size_ = %d;\n",
+ prefix, source_data.length());
+ }
+ fprintf(fp_, "\n");
}
- void WriteSnapshot() {
- Print(fp_);
+ void WriteMeta(const char* prefix, const i::Serializer& ser) const {
+ WriteSizeVar(ser, prefix, "new", i::NEW_SPACE);
+ WriteSizeVar(ser, prefix, "pointer", i::OLD_POINTER_SPACE);
+ WriteSizeVar(ser, prefix, "data", i::OLD_DATA_SPACE);
+ WriteSizeVar(ser, prefix, "code", i::CODE_SPACE);
+ WriteSizeVar(ser, prefix, "map", i::MAP_SPACE);
+ WriteSizeVar(ser, prefix, "cell", i::CELL_SPACE);
+ WriteSizeVar(ser, prefix, "property_cell", i::PROPERTY_CELL_SPACE);
+ fprintf(fp_, "\n");
}
- PartialSnapshotSink* partial_sink() { return &partial_sink_; }
+ void WriteSizeVar(const i::Serializer& ser, const char* prefix,
+ const char* name, int space) const {
+ fprintf(fp_, "const int Snapshot::%s%s_space_used_ = %d;\n",
+ prefix, name, ser.CurrentAllocationAddress(space));
+ }
+
+ void WriteSnapshotData(const i::List<char>* data) const {
+ for (int i = 0; i < data->length(); i++) {
+ if ((i & 0x1f) == 0x1f)
+ fprintf(fp_, "\n");
+ if (i > 0)
+ fprintf(fp_, ",");
+ fprintf(fp_, "%u", static_cast<unsigned char>(data->at(i)));
+ }
+ fprintf(fp_, "\n");
+ }
+
+ FILE* GetFileDescriptorOrDie(const char* filename) {
+ FILE* fp = i::OS::FOpen(filename, "wb");
+ if (fp == NULL) {
+ i::PrintF("Unable to open file \"%s\" for writing.\n", filename);
+ exit(1);
+ }
+ return fp;
+ }
- private:
FILE* fp_;
- PartialSnapshotSink partial_sink_;
+ FILE* raw_file_;
+ FILE* raw_context_file_;
+ Compressor* compressor_;
+ bool omit_;
};
@@ -274,7 +280,7 @@ int main(int argc, char** argv) {
// Print the usage if an error occurs when parsing the command line
// flags or if the help flag is set.
- int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
+ int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true, true);
if (result > 0 || argc != 2 || i::FLAG_help) {
::printf("Usage: %s [flag] ... outfile\n", argv[0]);
i::FlagList::PrintHelp();
@@ -293,7 +299,7 @@ int main(int argc, char** argv) {
Isolate* isolate = v8::Isolate::New();
isolate->Enter();
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
- i::Serializer::Enable(internal_isolate);
+ i::Serializer::RequestEnable(internal_isolate);
Persistent<Context> context;
{
HandleScope handle_scope(isolate);
@@ -359,46 +365,32 @@ int main(int argc, char** argv) {
i::Heap::kNoGCFlags, "mksnapshot");
i::Object* raw_context = *v8::Utils::OpenPersistent(context);
context.Reset();
- CppByteSink sink(argv[1]);
+
// This results in a somewhat smaller snapshot, probably because it gets rid
// of some things that are cached between garbage collections.
- i::StartupSerializer ser(internal_isolate, &sink);
+ i::List<char> snapshot_data;
+ ListSnapshotSink snapshot_sink(&snapshot_data);
+ i::StartupSerializer ser(internal_isolate, &snapshot_sink);
ser.SerializeStrongReferences();
- i::PartialSerializer partial_ser(
- internal_isolate, &ser, sink.partial_sink());
- partial_ser.Serialize(&raw_context);
-
+ i::List<char> context_data;
+ ListSnapshotSink contex_sink(&context_data);
+ i::PartialSerializer context_ser(internal_isolate, &ser, &contex_sink);
+ context_ser.Serialize(&raw_context);
ser.SerializeWeakReferences();
+ {
+ SnapshotWriter writer(argv[1]);
+ writer.SetOmit(i::FLAG_omit);
+ if (i::FLAG_raw_file && i::FLAG_raw_context_file)
+ writer.SetRawFiles(i::FLAG_raw_file, i::FLAG_raw_context_file);
#ifdef COMPRESS_STARTUP_DATA_BZ2
- BZip2Compressor compressor;
- if (!sink.Compress(&compressor))
- return 1;
- if (!sink.partial_sink()->Compress(&compressor))
- return 1;
+ BZip2Compressor bzip2;
+ writer.SetCompressor(&bzip2);
#endif
- sink.WriteSnapshot();
- sink.WritePartialSnapshot();
-
- sink.WriteSpaceUsed(
- "context_",
- partial_ser.CurrentAllocationAddress(i::NEW_SPACE),
- partial_ser.CurrentAllocationAddress(i::OLD_POINTER_SPACE),
- partial_ser.CurrentAllocationAddress(i::OLD_DATA_SPACE),
- partial_ser.CurrentAllocationAddress(i::CODE_SPACE),
- partial_ser.CurrentAllocationAddress(i::MAP_SPACE),
- partial_ser.CurrentAllocationAddress(i::CELL_SPACE),
- partial_ser.CurrentAllocationAddress(i::PROPERTY_CELL_SPACE));
- sink.WriteSpaceUsed(
- "",
- ser.CurrentAllocationAddress(i::NEW_SPACE),
- ser.CurrentAllocationAddress(i::OLD_POINTER_SPACE),
- ser.CurrentAllocationAddress(i::OLD_DATA_SPACE),
- ser.CurrentAllocationAddress(i::CODE_SPACE),
- ser.CurrentAllocationAddress(i::MAP_SPACE),
- ser.CurrentAllocationAddress(i::CELL_SPACE),
- ser.CurrentAllocationAddress(i::PROPERTY_CELL_SPACE));
+ writer.WriteSnapshot(snapshot_data, ser, context_data, context_ser);
+ }
+
isolate->Exit();
isolate->Dispose();
V8::Dispose();
diff --git a/deps/v8/src/msan.h b/deps/v8/src/msan.h
index 484c9fa397..5282583af5 100644
--- a/deps/v8/src/msan.h
+++ b/deps/v8/src/msan.h
@@ -1,35 +1,14 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// MemorySanitizer support.
#ifndef V8_MSAN_H_
#define V8_MSAN_H_
+#include "globals.h"
+
#ifndef __has_feature
# define __has_feature(x) 0
#endif
@@ -38,12 +17,12 @@
# define MEMORY_SANITIZER
#endif
-#ifdef MEMORY_SANITIZER
-# include <sanitizer/msan_interface.h>
+#if defined(MEMORY_SANITIZER) && !defined(USE_SIMULATOR)
+# include <sanitizer/msan_interface.h> // NOLINT
// Marks a memory range as fully initialized.
-# define MSAN_MEMORY_IS_INITIALIZED(p, s) __msan_unpoison((p), (s))
+# define MSAN_MEMORY_IS_INITIALIZED_IN_JIT(p, s) __msan_unpoison((p), (s))
#else
-# define MSAN_MEMORY_IS_INITIALIZED(p, s)
+# define MSAN_MEMORY_IS_INITIALIZED_IN_JIT(p, s)
#endif
#endif // V8_MSAN_H_
diff --git a/deps/v8/src/natives.h b/deps/v8/src/natives.h
index 5f34420d0b..2f930dc7bd 100644
--- a/deps/v8/src/natives.h
+++ b/deps/v8/src/natives.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_NATIVES_H_
#define V8_NATIVES_H_
diff --git a/deps/v8/src/object-observe.js b/deps/v8/src/object-observe.js
index e822f0bd49..532b0d2525 100644
--- a/deps/v8/src/object-observe.js
+++ b/deps/v8/src/object-observe.js
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
"use strict";
@@ -79,14 +56,11 @@ function GetWeakMapWrapper() {
};
MapWrapper.prototype = {
+ __proto__: null,
get: function(key) {
- key = %UnwrapGlobalProxy(key);
- if (!IS_SPEC_OBJECT(key)) return UNDEFINED;
return %WeakCollectionGet(this.map_, key);
},
set: function(key, value) {
- key = %UnwrapGlobalProxy(key);
- if (!IS_SPEC_OBJECT(key)) return UNDEFINED;
%WeakCollectionSet(this.map_, key, value);
},
has: function(key) {
@@ -382,6 +356,8 @@ function CallbackInfoNormalize(callback) {
function ObjectObserve(object, callback, acceptList) {
if (!IS_SPEC_OBJECT(object))
throw MakeTypeError("observe_non_object", ["observe"]);
+ if (%IsJSGlobalProxy(object))
+ throw MakeTypeError("observe_global_proxy", ["observe"]);
if (!IS_SPEC_FUNCTION(callback))
throw MakeTypeError("observe_non_function", ["observe"]);
if (ObjectIsFrozen(callback))
@@ -389,6 +365,10 @@ function ObjectObserve(object, callback, acceptList) {
if (!AcceptArgIsValid(acceptList))
throw MakeTypeError("observe_accept_invalid");
+ return %ObjectObserveInObjectContext(object, callback, acceptList);
+}
+
+function NativeObjectObserve(object, callback, acceptList) {
var objectInfo = ObjectInfoGetOrCreate(object);
ObjectInfoAddObserver(objectInfo, callback, acceptList);
return object;
@@ -397,6 +377,8 @@ function ObjectObserve(object, callback, acceptList) {
function ObjectUnobserve(object, callback) {
if (!IS_SPEC_OBJECT(object))
throw MakeTypeError("observe_non_object", ["unobserve"]);
+ if (%IsJSGlobalProxy(object))
+ throw MakeTypeError("observe_global_proxy", ["unobserve"]);
if (!IS_SPEC_FUNCTION(callback))
throw MakeTypeError("observe_non_function", ["unobserve"]);
@@ -419,27 +401,22 @@ function ArrayUnobserve(object, callback) {
return ObjectUnobserve(object, callback);
}
-function ObserverEnqueueIfActive(observer, objectInfo, changeRecord,
- needsAccessCheck) {
+function ObserverEnqueueIfActive(observer, objectInfo, changeRecord) {
if (!ObserverIsActive(observer, objectInfo) ||
!TypeMapHasType(ObserverGetAcceptTypes(observer), changeRecord.type)) {
return;
}
var callback = ObserverGetCallback(observer);
- if (needsAccessCheck &&
- // Drop all splice records on the floor for access-checked objects
- (changeRecord.type == 'splice' ||
- !%IsAccessAllowedForObserver(
- callback, changeRecord.object, changeRecord.name))) {
+ if (!%ObserverObjectAndRecordHaveSameOrigin(callback, changeRecord.object,
+ changeRecord)) {
return;
}
var callbackInfo = CallbackInfoNormalize(callback);
if (IS_NULL(GetPendingObservers())) {
SetPendingObservers(nullProtoObject())
- GetMicrotaskQueue().push(ObserveMicrotaskRunner);
- %SetMicrotaskPending(true);
+ EnqueueMicrotask(ObserveMicrotaskRunner);
}
GetPendingObservers()[callbackInfo.priority] = callback;
callbackInfo.push(changeRecord);
@@ -461,22 +438,16 @@ function ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, type) {
}
ObjectFreeze(newRecord);
- ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord,
- true /* skip access check */);
+ ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord);
}
-function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord,
- skipAccessCheck) {
+function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord) {
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (IS_SYMBOL(changeRecord.name)) return;
- var needsAccessCheck = !skipAccessCheck &&
- %IsAccessCheckNeeded(changeRecord.object);
-
if (ChangeObserversIsOptimized(objectInfo.changeObservers)) {
var observer = objectInfo.changeObservers;
- ObserverEnqueueIfActive(observer, objectInfo, changeRecord,
- needsAccessCheck);
+ ObserverEnqueueIfActive(observer, objectInfo, changeRecord);
return;
}
@@ -484,8 +455,7 @@ function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord,
var observer = objectInfo.changeObservers[priority];
if (IS_NULL(observer))
continue;
- ObserverEnqueueIfActive(observer, objectInfo, changeRecord,
- needsAccessCheck);
+ ObserverEnqueueIfActive(observer, objectInfo, changeRecord);
}
}
@@ -562,7 +532,6 @@ function ObjectNotifierPerformChange(changeType, changeFn) {
throw MakeTypeError("called_on_non_object", ["performChange"]);
var objectInfo = ObjectInfoGetFromNotifier(this);
-
if (IS_UNDEFINED(objectInfo))
throw MakeTypeError("observe_notify_non_notifier");
if (!IS_STRING(changeType))
@@ -570,6 +539,11 @@ function ObjectNotifierPerformChange(changeType, changeFn) {
if (!IS_SPEC_FUNCTION(changeFn))
throw MakeTypeError("observe_perform_non_function");
+ return %ObjectNotifierPerformChangeInObjectContext(
+ objectInfo, changeType, changeFn);
+}
+
+function NativeObjectNotifierPerformChange(objectInfo, changeType, changeFn) {
ObjectInfoAddPerformingType(objectInfo, changeType);
var changeRecord;
@@ -586,9 +560,17 @@ function ObjectNotifierPerformChange(changeType, changeFn) {
function ObjectGetNotifier(object) {
if (!IS_SPEC_OBJECT(object))
throw MakeTypeError("observe_non_object", ["getNotifier"]);
+ if (%IsJSGlobalProxy(object))
+ throw MakeTypeError("observe_global_proxy", ["getNotifier"]);
if (ObjectIsFrozen(object)) return null;
+ if (!%ObjectWasCreatedInCurrentOrigin(object)) return null;
+
+ return %ObjectGetNotifierInObjectContext(object);
+}
+
+function NativeObjectGetNotifier(object) {
var objectInfo = ObjectInfoGetOrCreate(object);
return ObjectInfoGetNotifier(objectInfo);
}
diff --git a/deps/v8/src/objects-debug.cc b/deps/v8/src/objects-debug.cc
index ca025e6cf6..7b7c9c9a70 100644
--- a/deps/v8/src/objects-debug.cc
+++ b/deps/v8/src/objects-debug.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -38,16 +15,11 @@ namespace internal {
#ifdef VERIFY_HEAP
-void MaybeObject::Verify() {
- Object* this_as_object;
- if (ToObject(&this_as_object)) {
- if (this_as_object->IsSmi()) {
- Smi::cast(this_as_object)->SmiVerify();
- } else {
- HeapObject::cast(this_as_object)->HeapObjectVerify();
- }
+void Object::ObjectVerify() {
+ if (IsSmi()) {
+ Smi::cast(this)->SmiVerify();
} else {
- Failure::cast(this)->FailureVerify();
+ HeapObject::cast(this)->HeapObjectVerify();
}
}
@@ -66,11 +38,6 @@ void Smi::SmiVerify() {
}
-void Failure::FailureVerify() {
- CHECK(IsFailure());
-}
-
-
void HeapObject::HeapObjectVerify() {
InstanceType instance_type = map()->instance_type();
@@ -165,6 +132,12 @@ void HeapObject::HeapObjectVerify() {
case JS_MAP_TYPE:
JSMap::cast(this)->JSMapVerify();
break;
+ case JS_SET_ITERATOR_TYPE:
+ JSSetIterator::cast(this)->JSSetIteratorVerify();
+ break;
+ case JS_MAP_ITERATOR_TYPE:
+ JSMapIterator::cast(this)->JSMapIteratorVerify();
+ break;
case JS_WEAK_MAP_TYPE:
JSWeakMap::cast(this)->JSWeakMapVerify();
break;
@@ -294,6 +267,12 @@ void JSObject::JSObjectVerify() {
if (value->IsUninitialized()) continue;
if (r.IsSmi()) ASSERT(value->IsSmi());
if (r.IsHeapObject()) ASSERT(value->IsHeapObject());
+ HeapType* field_type = descriptors->GetFieldType(i);
+ if (r.IsNone()) {
+ CHECK(field_type->Is(HeapType::None()));
+ } else if (!HeapType::Any()->Is(field_type)) {
+ CHECK(!field_type->NowStable() || field_type->NowContains(value));
+ }
}
}
}
@@ -368,7 +347,6 @@ void PolymorphicCodeCache::PolymorphicCodeCacheVerify() {
void TypeFeedbackInfo::TypeFeedbackInfoVerify() {
VerifyObjectField(kStorage1Offset);
VerifyObjectField(kStorage2Offset);
- VerifyHeapPointer(feedback_vector());
}
@@ -380,11 +358,7 @@ void AliasedArgumentsEntry::AliasedArgumentsEntryVerify() {
void FixedArray::FixedArrayVerify() {
for (int i = 0; i < length(); i++) {
Object* e = get(i);
- if (e->IsHeapObject()) {
- VerifyHeapPointer(e);
- } else {
- e->Verify();
- }
+ VerifyPointer(e);
}
}
@@ -521,6 +495,7 @@ void ConsString::ConsStringVerify() {
CHECK(this->second() == GetHeap()->empty_string() ||
this->second()->IsString());
CHECK(this->length() >= ConsString::kMinLength);
+ CHECK(this->length() == this->first()->length() + this->second()->length());
if (this->IsFlat()) {
// A flat cons can only be created by String::SlowTryFlatten.
// Afterwards, the first part may be externalized.
@@ -552,6 +527,7 @@ void SharedFunctionInfo::SharedFunctionInfoVerify() {
VerifyObjectField(kNameOffset);
VerifyObjectField(kCodeOffset);
VerifyObjectField(kOptimizedCodeMapOffset);
+ VerifyObjectField(kFeedbackVectorOffset);
VerifyObjectField(kScopeInfoOffset);
VerifyObjectField(kInstanceClassNameOffset);
VerifyObjectField(kFunctionDataOffset);
@@ -595,18 +571,41 @@ void JSBuiltinsObject::JSBuiltinsObjectVerify() {
void Oddball::OddballVerify() {
CHECK(IsOddball());
+ Heap* heap = GetHeap();
VerifyHeapPointer(to_string());
Object* number = to_number();
if (number->IsHeapObject()) {
- CHECK(number == HeapObject::cast(number)->GetHeap()->nan_value());
+ CHECK(number == heap->nan_value());
} else {
CHECK(number->IsSmi());
int value = Smi::cast(number)->value();
// Hidden oddballs have negative smis.
- const int kLeastHiddenOddballNumber = -4;
+ const int kLeastHiddenOddballNumber = -5;
CHECK_LE(value, 1);
CHECK(value >= kLeastHiddenOddballNumber);
}
+ if (map() == heap->undefined_map()) {
+ CHECK(this == heap->undefined_value());
+ } else if (map() == heap->the_hole_map()) {
+ CHECK(this == heap->the_hole_value());
+ } else if (map() == heap->null_map()) {
+ CHECK(this == heap->null_value());
+ } else if (map() == heap->boolean_map()) {
+ CHECK(this == heap->true_value() ||
+ this == heap->false_value());
+ } else if (map() == heap->uninitialized_map()) {
+ CHECK(this == heap->uninitialized_value());
+ } else if (map() == heap->no_interceptor_result_sentinel_map()) {
+ CHECK(this == heap->no_interceptor_result_sentinel());
+ } else if (map() == heap->arguments_marker_map()) {
+ CHECK(this == heap->arguments_marker());
+ } else if (map() == heap->termination_exception_map()) {
+ CHECK(this == heap->termination_exception());
+ } else if (map() == heap->exception_map()) {
+ CHECK(this == heap->exception());
+ } else {
+ UNREACHABLE();
+ }
}
@@ -626,10 +625,11 @@ void PropertyCell::PropertyCellVerify() {
void Code::CodeVerify() {
CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
kCodeAlignment));
- relocation_info()->Verify();
+ relocation_info()->ObjectVerify();
Address last_gc_pc = NULL;
+ Isolate* isolate = GetIsolate();
for (RelocIterator it(this); !it.done(); it.next()) {
- it.rinfo()->Verify();
+ it.rinfo()->Verify(isolate);
// Ensure that GC will not iterate twice over the same pointer.
if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
CHECK(it.rinfo()->pc() != last_gc_pc);
@@ -640,19 +640,25 @@ void Code::CodeVerify() {
void Code::VerifyEmbeddedObjectsDependency() {
+ if (!CanContainWeakObjects()) return;
+ DisallowHeapAllocation no_gc;
+ Isolate* isolate = GetIsolate();
+ HandleScope scope(isolate);
int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
Object* obj = it.rinfo()->target_object();
if (IsWeakObject(obj)) {
if (obj->IsMap()) {
Map* map = Map::cast(obj);
- CHECK(map->dependent_code()->Contains(
- DependentCode::kWeaklyEmbeddedGroup, this));
+ DependentCode::DependencyGroup group = is_optimized_code() ?
+ DependentCode::kWeakCodeGroup : DependentCode::kWeakICGroup;
+ CHECK(map->dependent_code()->Contains(group, this));
} else if (obj->IsJSObject()) {
Object* raw_table = GetIsolate()->heap()->weak_object_to_code_table();
WeakHashTable* table = WeakHashTable::cast(raw_table);
- CHECK(DependentCode::cast(table->Lookup(obj))->Contains(
- DependentCode::kWeaklyEmbeddedGroup, this));
+ Handle<Object> key_obj(obj, isolate);
+ CHECK(DependentCode::cast(table->Lookup(key_obj))->Contains(
+ DependentCode::kWeakCodeGroup, this));
}
}
}
@@ -676,7 +682,8 @@ void JSSet::JSSetVerify() {
CHECK(IsJSSet());
JSObjectVerify();
VerifyHeapPointer(table());
- CHECK(table()->IsHashTable() || table()->IsUndefined());
+ CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
+ // TODO(arv): Verify OrderedHashTable too.
}
@@ -684,7 +691,40 @@ void JSMap::JSMapVerify() {
CHECK(IsJSMap());
JSObjectVerify();
VerifyHeapPointer(table());
- CHECK(table()->IsHashTable() || table()->IsUndefined());
+ CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
+ // TODO(arv): Verify OrderedHashTable too.
+}
+
+
+void JSSetIterator::JSSetIteratorVerify() {
+ CHECK(IsJSSetIterator());
+ JSObjectVerify();
+ VerifyHeapPointer(table());
+ CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
+ CHECK(index()->IsSmi());
+ CHECK(count()->IsSmi());
+ CHECK(kind()->IsSmi());
+ VerifyHeapPointer(next_iterator());
+ CHECK(next_iterator()->IsJSSetIterator() || next_iterator()->IsUndefined());
+ VerifyHeapPointer(table());
+ CHECK(previous_iterator()->IsJSSetIterator()
+ || previous_iterator()->IsUndefined());
+}
+
+
+void JSMapIterator::JSMapIteratorVerify() {
+ CHECK(IsJSMapIterator());
+ JSObjectVerify();
+ VerifyHeapPointer(table());
+ CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
+ CHECK(index()->IsSmi());
+ CHECK(count()->IsSmi());
+ CHECK(kind()->IsSmi());
+ VerifyHeapPointer(next_iterator());
+ CHECK(next_iterator()->IsJSMapIterator() || next_iterator()->IsUndefined());
+ VerifyHeapPointer(table());
+ CHECK(previous_iterator()->IsJSMapIterator()
+ || previous_iterator()->IsUndefined());
}
@@ -811,7 +851,7 @@ void Foreign::ForeignVerify() {
void Box::BoxVerify() {
CHECK(IsBox());
- value()->Verify();
+ value()->ObjectVerify();
}
@@ -947,7 +987,7 @@ void Script::ScriptVerify() {
void JSFunctionResultCache::JSFunctionResultCacheVerify() {
- JSFunction::cast(get(kFactoryIndex))->Verify();
+ JSFunction::cast(get(kFactoryIndex))->ObjectVerify();
int size = Smi::cast(get(kCacheSizeIndex))->value();
CHECK(kEntriesIndex <= size);
@@ -962,21 +1002,21 @@ void JSFunctionResultCache::JSFunctionResultCacheVerify() {
if (FLAG_enable_slow_asserts) {
for (int i = kEntriesIndex; i < size; i++) {
CHECK(!get(i)->IsTheHole());
- get(i)->Verify();
+ get(i)->ObjectVerify();
}
for (int i = size; i < length(); i++) {
CHECK(get(i)->IsTheHole());
- get(i)->Verify();
+ get(i)->ObjectVerify();
}
}
}
void NormalizedMapCache::NormalizedMapCacheVerify() {
- FixedArray::cast(this)->Verify();
+ FixedArray::cast(this)->FixedArrayVerify();
if (FLAG_enable_slow_asserts) {
for (int i = 0; i < length(); i++) {
- Object* e = get(i);
+ Object* e = FixedArray::get(i);
if (e->IsMap()) {
Map::cast(e)->SharedMapVerify();
} else {
@@ -987,7 +1027,6 @@ void NormalizedMapCache::NormalizedMapCacheVerify() {
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
void DebugInfo::DebugInfoVerify() {
CHECK(IsDebugInfo());
VerifyPointer(shared());
@@ -1004,7 +1043,6 @@ void BreakPointInfo::BreakPointInfoVerify() {
statement_position()->SmiVerify();
VerifyPointer(break_point_objects());
}
-#endif // ENABLE_DEBUGGER_SUPPORT
#endif // VERIFY_HEAP
#ifdef DEBUG
diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h
index 9d550374e0..029e80d9bb 100644
--- a/deps/v8/src/objects-inl.h
+++ b/deps/v8/src/objects-inl.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
//
// Review notes:
//
@@ -87,13 +64,6 @@ PropertyDetails PropertyDetails::AsDeleted() const {
}
-#define FIXED_TYPED_ARRAY_CAST_ACCESSOR(type) \
- template<> \
- type* type::cast(Object* object) { \
- SLOW_ASSERT(object->Is##type()); \
- return reinterpret_cast<type*>(object); \
- }
-
#define INT_ACCESSORS(holder, name, offset) \
int holder::name() { return READ_INT_FIELD(this, offset); } \
void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
@@ -125,6 +95,23 @@ PropertyDetails PropertyDetails::AsDeleted() const {
WRITE_FIELD(this, offset, Smi::FromInt(value)); \
}
+#define SYNCHRONIZED_SMI_ACCESSORS(holder, name, offset) \
+ int holder::synchronized_##name() { \
+ Object* value = ACQUIRE_READ_FIELD(this, offset); \
+ return Smi::cast(value)->value(); \
+ } \
+ void holder::synchronized_set_##name(int value) { \
+ RELEASE_WRITE_FIELD(this, offset, Smi::FromInt(value)); \
+ }
+
+#define NOBARRIER_SMI_ACCESSORS(holder, name, offset) \
+ int holder::nobarrier_##name() { \
+ Object* value = NOBARRIER_READ_FIELD(this, offset); \
+ return Smi::cast(value)->value(); \
+ } \
+ void holder::nobarrier_set_##name(int value) { \
+ NOBARRIER_WRITE_FIELD(this, offset, Smi::FromInt(value)); \
+ }
#define BOOL_GETTER(holder, field, name, offset) \
bool holder::name() { \
@@ -170,12 +157,6 @@ bool Object::IsHeapObject() {
}
-bool Object::NonFailureIsHeapObject() {
- ASSERT(!this->IsFailure());
- return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
-}
-
-
TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
TYPE_CHECKER(Symbol, SYMBOL_TYPE)
@@ -209,6 +190,11 @@ bool Object::IsSpecFunction() {
}
+bool Object::IsTemplateInfo() {
+ return IsObjectTemplateInfo() || IsFunctionTemplateInfo();
+}
+
+
bool Object::IsInternalizedString() {
if (!this->IsHeapObject()) return false;
uint32_t type = HeapObject::cast(this)->map()->instance_type();
@@ -269,6 +255,7 @@ bool Object::IsExternalTwoByteString() {
String::cast(this)->IsTwoByteRepresentation();
}
+
bool Object::HasValidElements() {
// Dictionary is covered under FixedArray.
return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray() ||
@@ -276,16 +263,17 @@ bool Object::HasValidElements() {
}
-MaybeObject* Object::AllocateNewStorageFor(Heap* heap,
- Representation representation) {
- if (representation.IsSmi() && IsUninitialized()) {
- return Smi::FromInt(0);
+Handle<Object> Object::NewStorageFor(Isolate* isolate,
+ Handle<Object> object,
+ Representation representation) {
+ if (representation.IsSmi() && object->IsUninitialized()) {
+ return handle(Smi::FromInt(0), isolate);
}
- if (!representation.IsDouble()) return this;
- if (IsUninitialized()) {
- return heap->AllocateHeapNumber(0);
+ if (!representation.IsDouble()) return object;
+ if (object->IsUninitialized()) {
+ return isolate->factory()->NewHeapNumber(0);
}
- return heap->AllocateHeapNumber(Number());
+ return isolate->factory()->NewHeapNumber(object->Number());
}
@@ -458,13 +446,34 @@ uc32 FlatStringReader::Get(int index) {
}
+Handle<Object> StringTableShape::AsHandle(Isolate* isolate, HashTableKey* key) {
+ return key->AsHandle(isolate);
+}
+
+
+Handle<Object> MapCacheShape::AsHandle(Isolate* isolate, HashTableKey* key) {
+ return key->AsHandle(isolate);
+}
+
+
+Handle<Object> CompilationCacheShape::AsHandle(Isolate* isolate,
+ HashTableKey* key) {
+ return key->AsHandle(isolate);
+}
+
+
+Handle<Object> CodeCacheHashTableShape::AsHandle(Isolate* isolate,
+ HashTableKey* key) {
+ return key->AsHandle(isolate);
+}
+
template <typename Char>
class SequentialStringKey : public HashTableKey {
public:
explicit SequentialStringKey(Vector<const Char> string, uint32_t seed)
: string_(string), hash_field_(0), seed_(seed) { }
- virtual uint32_t Hash() {
+ virtual uint32_t Hash() V8_OVERRIDE {
hash_field_ = StringHasher::HashSequentialString<Char>(string_.start(),
string_.length(),
seed_);
@@ -475,7 +484,7 @@ class SequentialStringKey : public HashTableKey {
}
- virtual uint32_t HashForObject(Object* other) {
+ virtual uint32_t HashForObject(Object* other) V8_OVERRIDE {
return String::cast(other)->Hash();
}
@@ -490,11 +499,11 @@ class OneByteStringKey : public SequentialStringKey<uint8_t> {
OneByteStringKey(Vector<const uint8_t> str, uint32_t seed)
: SequentialStringKey<uint8_t>(str, seed) { }
- virtual bool IsMatch(Object* string) {
+ virtual bool IsMatch(Object* string) V8_OVERRIDE {
return String::cast(string)->IsOneByteEqualTo(string_);
}
- virtual MaybeObject* AsObject(Heap* heap);
+ virtual Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE;
};
@@ -509,7 +518,7 @@ class SubStringKey : public HashTableKey {
ASSERT(string_->IsSeqString() || string->IsExternalString());
}
- virtual uint32_t Hash() {
+ virtual uint32_t Hash() V8_OVERRIDE {
ASSERT(length_ >= 0);
ASSERT(from_ + length_ <= string_->length());
const Char* chars = GetChars() + from_;
@@ -520,12 +529,12 @@ class SubStringKey : public HashTableKey {
return result;
}
- virtual uint32_t HashForObject(Object* other) {
+ virtual uint32_t HashForObject(Object* other) V8_OVERRIDE {
return String::cast(other)->Hash();
}
- virtual bool IsMatch(Object* string);
- virtual MaybeObject* AsObject(Heap* heap);
+ virtual bool IsMatch(Object* string) V8_OVERRIDE;
+ virtual Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE;
private:
const Char* GetChars();
@@ -550,11 +559,11 @@ class TwoByteStringKey : public SequentialStringKey<uc16> {
explicit TwoByteStringKey(Vector<const uc16> str, uint32_t seed)
: SequentialStringKey<uc16>(str, seed) { }
- virtual bool IsMatch(Object* string) {
+ virtual bool IsMatch(Object* string) V8_OVERRIDE {
return String::cast(string)->IsTwoByteEqualTo(string_);
}
- virtual MaybeObject* AsObject(Heap* heap);
+ virtual Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE;
};
@@ -564,11 +573,11 @@ class Utf8StringKey : public HashTableKey {
explicit Utf8StringKey(Vector<const char> string, uint32_t seed)
: string_(string), hash_field_(0), seed_(seed) { }
- virtual bool IsMatch(Object* string) {
+ virtual bool IsMatch(Object* string) V8_OVERRIDE {
return String::cast(string)->IsUtf8EqualTo(string_);
}
- virtual uint32_t Hash() {
+ virtual uint32_t Hash() V8_OVERRIDE {
if (hash_field_ != 0) return hash_field_ >> String::kHashShift;
hash_field_ = StringHasher::ComputeUtf8Hash(string_, seed_, &chars_);
uint32_t result = hash_field_ >> String::kHashShift;
@@ -576,15 +585,14 @@ class Utf8StringKey : public HashTableKey {
return result;
}
- virtual uint32_t HashForObject(Object* other) {
+ virtual uint32_t HashForObject(Object* other) V8_OVERRIDE {
return String::cast(other)->Hash();
}
- virtual MaybeObject* AsObject(Heap* heap) {
+ virtual Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE {
if (hash_field_ == 0) Hash();
- return heap->AllocateInternalizedStringFromUtf8(string_,
- chars_,
- hash_field_);
+ return isolate->factory()->NewInternalizedStringFromUtf8(
+ string_, chars_, hash_field_);
}
Vector<const char> string_;
@@ -638,38 +646,6 @@ bool Object::IsFixedTypedArrayBase() {
}
-bool MaybeObject::IsFailure() {
- return HAS_FAILURE_TAG(this);
-}
-
-
-bool MaybeObject::IsRetryAfterGC() {
- return HAS_FAILURE_TAG(this)
- && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
-}
-
-
-bool MaybeObject::IsException() {
- return this == Failure::Exception();
-}
-
-
-bool MaybeObject::IsTheHole() {
- return !IsFailure() && ToObjectUnchecked()->IsTheHole();
-}
-
-
-bool MaybeObject::IsUninitialized() {
- return !IsFailure() && ToObjectUnchecked()->IsUninitialized();
-}
-
-
-Failure* Failure::cast(MaybeObject* obj) {
- ASSERT(HAS_FAILURE_TAG(obj));
- return reinterpret_cast<Failure*>(obj);
-}
-
-
bool Object::IsJSReceiver() {
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
return IsHeapObject() &&
@@ -694,6 +670,8 @@ bool Object::IsJSProxy() {
TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
TYPE_CHECKER(JSSet, JS_SET_TYPE)
TYPE_CHECKER(JSMap, JS_MAP_TYPE)
+TYPE_CHECKER(JSSetIterator, JS_SET_ITERATOR_TYPE)
+TYPE_CHECKER(JSMapIterator, JS_MAP_ITERATOR_TYPE)
TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
TYPE_CHECKER(JSWeakSet, JS_WEAK_SET_TYPE)
TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
@@ -848,8 +826,7 @@ bool Object::IsDictionary() {
bool Object::IsStringTable() {
- return IsHashTable() &&
- this == HeapObject::cast(this)->GetHeap()->raw_unchecked_string_table();
+ return IsHashTable();
}
@@ -873,13 +850,23 @@ bool Object::IsJSFunctionResultCache() {
bool Object::IsNormalizedMapCache() {
- if (!IsFixedArray()) return false;
- if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
+ return NormalizedMapCache::IsNormalizedMapCache(this);
+}
+
+
+int NormalizedMapCache::GetIndex(Handle<Map> map) {
+ return map->Hash() % NormalizedMapCache::kEntries;
+}
+
+
+bool NormalizedMapCache::IsNormalizedMapCache(Object* obj) {
+ if (!obj->IsFixedArray()) return false;
+ if (FixedArray::cast(obj)->length() != NormalizedMapCache::kEntries) {
return false;
}
#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
- reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
+ reinterpret_cast<NormalizedMapCache*>(obj)->NormalizedMapCacheVerify();
}
#endif
return true;
@@ -911,6 +898,13 @@ bool Object::IsObjectHashTable() {
}
+bool Object::IsOrderedHashTable() {
+ return IsHeapObject() &&
+ HeapObject::cast(this)->map() ==
+ HeapObject::cast(this)->GetHeap()->ordered_hash_table_map();
+}
+
+
bool Object::IsPrimitive() {
return IsOddball() || IsNumber() || IsString();
}
@@ -992,6 +986,11 @@ bool Object::IsTheHole() {
}
+bool Object::IsException() {
+ return IsOddball() && Oddball::cast(this)->kind() == Oddball::kException;
+}
+
+
bool Object::IsUninitialized() {
return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUninitialized;
}
@@ -1025,8 +1024,8 @@ bool Object::IsNaN() {
}
-Handle<Object> Object::ToSmi(Isolate* isolate, Handle<Object> object) {
- if (object->IsSmi()) return object;
+MaybeHandle<Smi> Object::ToSmi(Isolate* isolate, Handle<Object> object) {
+ if (object->IsSmi()) return Handle<Smi>::cast(object);
if (object->IsHeapNumber()) {
double value = Handle<HeapNumber>::cast(object)->value();
int int_value = FastD2I(value);
@@ -1034,21 +1033,14 @@ Handle<Object> Object::ToSmi(Isolate* isolate, Handle<Object> object) {
return handle(Smi::FromInt(int_value), isolate);
}
}
- return Handle<Object>();
+ return Handle<Smi>();
}
-// TODO(ishell): Use handlified version instead.
-MaybeObject* Object::ToSmi() {
- if (IsSmi()) return this;
- if (IsHeapNumber()) {
- double value = HeapNumber::cast(this)->value();
- int int_value = FastD2I(value);
- if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
- return Smi::FromInt(int_value);
- }
- }
- return Failure::Exception();
+MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
+ Handle<Object> object) {
+ return ToObject(
+ isolate, object, handle(isolate->context()->native_context(), isolate));
}
@@ -1057,9 +1049,16 @@ bool Object::HasSpecificClassOf(String* name) {
}
-Handle<Object> Object::GetElement(Isolate* isolate,
- Handle<Object> object,
- uint32_t index) {
+MaybeHandle<Object> Object::GetProperty(Handle<Object> object,
+ Handle<Name> name) {
+ PropertyAttributes attributes;
+ return GetPropertyWithReceiver(object, object, name, &attributes);
+}
+
+
+MaybeHandle<Object> Object::GetElement(Isolate* isolate,
+ Handle<Object> object,
+ uint32_t index) {
// GetElement can trigger a getter which can cause allocation.
// This was not always the case. This ASSERT is here to catch
// leftover incorrect uses.
@@ -1068,24 +1067,52 @@ Handle<Object> Object::GetElement(Isolate* isolate,
}
-Handle<Object> Object::GetElementNoExceptionThrown(Isolate* isolate,
- Handle<Object> object,
+MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> object,
+ Handle<Name> name) {
+ uint32_t index;
+ Isolate* isolate = name->GetIsolate();
+ if (name->AsArrayIndex(&index)) return GetElement(isolate, object, index);
+ return GetProperty(object, name);
+}
+
+
+MaybeHandle<Object> Object::GetProperty(Isolate* isolate,
+ Handle<Object> object,
+ const char* name) {
+ Handle<String> str = isolate->factory()->InternalizeUtf8String(name);
+ ASSERT(!str.is_null());
+#ifdef DEBUG
+ uint32_t index; // Assert that the name is not an array index.
+ ASSERT(!str->AsArrayIndex(&index));
+#endif // DEBUG
+ return GetProperty(object, str);
+}
+
+
+MaybeHandle<Object> JSProxy::GetElementWithHandler(Handle<JSProxy> proxy,
+ Handle<Object> receiver,
uint32_t index) {
- Handle<Object> result =
- Object::GetElementWithReceiver(isolate, object, object, index);
- CHECK_NOT_EMPTY_HANDLE(isolate, result);
- return result;
+ return GetPropertyWithHandler(
+ proxy, receiver, proxy->GetIsolate()->factory()->Uint32ToString(index));
}
-MaybeObject* Object::GetProperty(Name* key) {
- PropertyAttributes attributes;
- return GetPropertyWithReceiver(this, key, &attributes);
+MaybeHandle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy,
+ Handle<JSReceiver> receiver,
+ uint32_t index,
+ Handle<Object> value,
+ StrictMode strict_mode) {
+ Isolate* isolate = proxy->GetIsolate();
+ Handle<String> name = isolate->factory()->Uint32ToString(index);
+ return SetPropertyWithHandler(
+ proxy, receiver, name, value, NONE, strict_mode);
}
-MaybeObject* Object::GetProperty(Name* key, PropertyAttributes* attributes) {
- return GetPropertyWithReceiver(this, key, attributes);
+bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) {
+ Isolate* isolate = proxy->GetIsolate();
+ Handle<String> name = isolate->factory()->Uint32ToString(index);
+ return HasPropertyWithHandler(proxy, name);
}
@@ -1095,9 +1122,25 @@ MaybeObject* Object::GetProperty(Name* key, PropertyAttributes* attributes) {
#define READ_FIELD(p, offset) \
(*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
+#define ACQUIRE_READ_FIELD(p, offset) \
+ reinterpret_cast<Object*>( \
+ Acquire_Load(reinterpret_cast<AtomicWord*>(FIELD_ADDR(p, offset))))
+
+#define NOBARRIER_READ_FIELD(p, offset) \
+ reinterpret_cast<Object*>( \
+ NoBarrier_Load(reinterpret_cast<AtomicWord*>(FIELD_ADDR(p, offset))))
+
#define WRITE_FIELD(p, offset, value) \
(*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
+#define RELEASE_WRITE_FIELD(p, offset, value) \
+ Release_Store(reinterpret_cast<AtomicWord*>(FIELD_ADDR(p, offset)), \
+ reinterpret_cast<AtomicWord>(value));
+
+#define NOBARRIER_WRITE_FIELD(p, offset, value) \
+ NoBarrier_Store(reinterpret_cast<AtomicWord*>(FIELD_ADDR(p, offset)), \
+ reinterpret_cast<AtomicWord>(value));
+
#define WRITE_BARRIER(heap, object, offset, value) \
heap->incremental_marking()->RecordWrite( \
object, HeapObject::RawField(object, offset), value); \
@@ -1192,9 +1235,16 @@ MaybeObject* Object::GetProperty(Name* key, PropertyAttributes* attributes) {
#define READ_BYTE_FIELD(p, offset) \
(*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
+#define NOBARRIER_READ_BYTE_FIELD(p, offset) \
+ static_cast<byte>(NoBarrier_Load( \
+ reinterpret_cast<Atomic8*>(FIELD_ADDR(p, offset))) )
+
#define WRITE_BYTE_FIELD(p, offset, value) \
(*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
+#define NOBARRIER_WRITE_BYTE_FIELD(p, offset, value) \
+ NoBarrier_Store(reinterpret_cast<Atomic8*>(FIELD_ADDR(p, offset)), \
+ static_cast<Atomic8>(value));
Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
return &READ_FIELD(obj, byte_offset);
@@ -1219,62 +1269,6 @@ Smi* Smi::FromIntptr(intptr_t value) {
}
-Failure::Type Failure::type() const {
- return static_cast<Type>(value() & kFailureTypeTagMask);
-}
-
-
-bool Failure::IsInternalError() const {
- return type() == INTERNAL_ERROR;
-}
-
-
-AllocationSpace Failure::allocation_space() const {
- ASSERT_EQ(RETRY_AFTER_GC, type());
- return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
- & kSpaceTagMask);
-}
-
-
-Failure* Failure::InternalError() {
- return Construct(INTERNAL_ERROR);
-}
-
-
-Failure* Failure::Exception() {
- return Construct(EXCEPTION);
-}
-
-
-intptr_t Failure::value() const {
- return static_cast<intptr_t>(
- reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
-}
-
-
-Failure* Failure::RetryAfterGC() {
- return RetryAfterGC(NEW_SPACE);
-}
-
-
-Failure* Failure::RetryAfterGC(AllocationSpace space) {
- ASSERT((space & ~kSpaceTagMask) == 0);
- return Construct(RETRY_AFTER_GC, space);
-}
-
-
-Failure* Failure::Construct(Type type, intptr_t value) {
- uintptr_t info =
- (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
- ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
- // Fill the unused bits with a pattern that's easy to recognize in crash
- // dumps.
- static const int kFailureMagicPattern = 0x0BAD0000;
- return reinterpret_cast<Failure*>(
- (info << kFailureTagSize) | kFailureTag | kFailureMagicPattern);
-}
-
-
bool Smi::IsValid(intptr_t value) {
bool result = Internals::IsValidSmi(value);
ASSERT_EQ(result, value >= kMinValue && value <= kMaxValue);
@@ -1348,6 +1342,26 @@ void HeapObject::set_map(Map* value) {
}
+Map* HeapObject::synchronized_map() {
+ return synchronized_map_word().ToMap();
+}
+
+
+void HeapObject::synchronized_set_map(Map* value) {
+ synchronized_set_map_word(MapWord::FromMap(value));
+ if (value != NULL) {
+ // TODO(1600) We are passing NULL as a slot because maps can never be on
+ // evacuation candidate.
+ value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
+ }
+}
+
+
+void HeapObject::synchronized_set_map_no_write_barrier(Map* value) {
+ synchronized_set_map_word(MapWord::FromMap(value));
+}
+
+
// Unsafe accessor omitting write barrier.
void HeapObject::set_map_no_write_barrier(Map* value) {
set_map_word(MapWord::FromMap(value));
@@ -1355,14 +1369,26 @@ void HeapObject::set_map_no_write_barrier(Map* value) {
MapWord HeapObject::map_word() {
- return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
+ return MapWord(
+ reinterpret_cast<uintptr_t>(NOBARRIER_READ_FIELD(this, kMapOffset)));
}
void HeapObject::set_map_word(MapWord map_word) {
- // WRITE_FIELD does not invoke write barrier, but there is no need
- // here.
- WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
+ NOBARRIER_WRITE_FIELD(
+ this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
+}
+
+
+MapWord HeapObject::synchronized_map_word() {
+ return MapWord(
+ reinterpret_cast<uintptr_t>(ACQUIRE_READ_FIELD(this, kMapOffset)));
+}
+
+
+void HeapObject::synchronized_set_map_word(MapWord map_word) {
+ RELEASE_WRITE_FIELD(
+ this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
}
@@ -1444,11 +1470,11 @@ FixedArrayBase* JSObject::elements() {
}
-void JSObject::ValidateElements() {
+void JSObject::ValidateElements(Handle<JSObject> object) {
#ifdef ENABLE_SLOW_ASSERTS
if (FLAG_enable_slow_asserts) {
- ElementsAccessor* accessor = GetElementsAccessor();
- accessor->Validate(this);
+ ElementsAccessor* accessor = object->GetElementsAccessor();
+ accessor->Validate(object);
}
#endif
}
@@ -1588,7 +1614,7 @@ inline bool AllocationSite::DigestPretenuringFeedback() {
void JSObject::EnsureCanContainHeapObjectElements(Handle<JSObject> object) {
- object->ValidateElements();
+ JSObject::ValidateElements(object);
ElementsKind elements_kind = object->map()->elements_kind();
if (!IsFastObjectElementsKind(elements_kind)) {
if (IsFastHoleyElementsKind(elements_kind)) {
@@ -1676,56 +1702,27 @@ void JSObject::EnsureCanContainElements(Handle<JSObject> object,
}
-MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
- ElementsKind to_kind) {
- Map* current_map = map();
- ElementsKind from_kind = current_map->elements_kind();
- if (from_kind == to_kind) return current_map;
-
- Context* native_context = isolate->context()->native_context();
- Object* maybe_array_maps = native_context->js_array_maps();
- if (maybe_array_maps->IsFixedArray()) {
- FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
- if (array_maps->get(from_kind) == current_map) {
- Object* maybe_transitioned_map = array_maps->get(to_kind);
- if (maybe_transitioned_map->IsMap()) {
- return Map::cast(maybe_transitioned_map);
- }
- }
- }
-
- return GetElementsTransitionMapSlow(to_kind);
+void JSObject::SetMapAndElements(Handle<JSObject> object,
+ Handle<Map> new_map,
+ Handle<FixedArrayBase> value) {
+ JSObject::MigrateToMap(object, new_map);
+ ASSERT((object->map()->has_fast_smi_or_object_elements() ||
+ (*value == object->GetHeap()->empty_fixed_array())) ==
+ (value->map() == object->GetHeap()->fixed_array_map() ||
+ value->map() == object->GetHeap()->fixed_cow_array_map()));
+ ASSERT((*value == object->GetHeap()->empty_fixed_array()) ||
+ (object->map()->has_fast_double_elements() ==
+ value->IsFixedDoubleArray()));
+ object->set_elements(*value);
}
-void JSObject::set_map_and_elements(Map* new_map,
- FixedArrayBase* value,
- WriteBarrierMode mode) {
- ASSERT(value->HasValidElements());
- if (new_map != NULL) {
- if (mode == UPDATE_WRITE_BARRIER) {
- set_map(new_map);
- } else {
- ASSERT(mode == SKIP_WRITE_BARRIER);
- set_map_no_write_barrier(new_map);
- }
- }
- ASSERT((map()->has_fast_smi_or_object_elements() ||
- (value == GetHeap()->empty_fixed_array())) ==
- (value->map() == GetHeap()->fixed_array_map() ||
- value->map() == GetHeap()->fixed_cow_array_map()));
- ASSERT((value == GetHeap()->empty_fixed_array()) ||
- (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
+void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
WRITE_FIELD(this, kElementsOffset, value);
CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
}
-void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
- set_map_and_elements(NULL, value, mode);
-}
-
-
void JSObject::initialize_properties() {
ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
@@ -1733,50 +1730,8 @@ void JSObject::initialize_properties() {
void JSObject::initialize_elements() {
- if (map()->has_fast_smi_or_object_elements() ||
- map()->has_fast_double_elements()) {
- ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
- WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
- } else if (map()->has_external_array_elements()) {
- ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(map());
- ASSERT(!GetHeap()->InNewSpace(empty_array));
- WRITE_FIELD(this, kElementsOffset, empty_array);
- } else if (map()->has_fixed_typed_array_elements()) {
- FixedTypedArrayBase* empty_array =
- GetHeap()->EmptyFixedTypedArrayForMap(map());
- ASSERT(!GetHeap()->InNewSpace(empty_array));
- WRITE_FIELD(this, kElementsOffset, empty_array);
- } else {
- UNREACHABLE();
- }
-}
-
-
-MaybeObject* JSObject::ResetElements() {
- if (map()->is_observed()) {
- // Maintain invariant that observed elements are always in dictionary mode.
- SeededNumberDictionary* dictionary;
- MaybeObject* maybe = SeededNumberDictionary::Allocate(GetHeap(), 0);
- if (!maybe->To(&dictionary)) return maybe;
- if (map() == GetHeap()->sloppy_arguments_elements_map()) {
- FixedArray::cast(elements())->set(1, dictionary);
- } else {
- set_elements(dictionary);
- }
- return this;
- }
-
- ElementsKind elements_kind = GetInitialFastElementsKind();
- if (!FLAG_smi_only_arrays) {
- elements_kind = FastSmiToObjectElementsKind(elements_kind);
- }
- MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind);
- Map* map;
- if (!maybe->To(&map)) return maybe;
- set_map(map);
- initialize_elements();
-
- return this;
+ FixedArrayBase* elements = map()->GetInitialElements();
+ WRITE_FIELD(this, kElementsOffset, elements);
}
@@ -1887,6 +1842,10 @@ int JSObject::GetHeaderSize() {
return JSSet::kSize;
case JS_MAP_TYPE:
return JSMap::kSize;
+ case JS_SET_ITERATOR_TYPE:
+ return JSSetIterator::kSize;
+ case JS_MAP_ITERATOR_TYPE:
+ return JSMapIterator::kSize;
case JS_WEAK_MAP_TYPE:
return JSWeakMap::kSize;
case JS_WEAK_SET_TYPE:
@@ -1951,13 +1910,6 @@ void JSObject::SetInternalField(int index, Smi* value) {
}
-MaybeObject* JSObject::FastPropertyAt(Representation representation,
- int index) {
- Object* raw_value = RawFastPropertyAt(index);
- return raw_value->AllocateNewStorageFor(GetHeap(), representation);
-}
-
-
// Access fast-case object properties at index. The use of these routines
// is needed to correctly distinguish between properties stored in-object and
// properties stored in the properties array.
@@ -2130,6 +2082,11 @@ Object* FixedArray::get(int index) {
}
+Handle<Object> FixedArray::get(Handle<FixedArray> array, int index) {
+ return handle(array->get(index), array->GetIsolate());
+}
+
+
bool FixedArray::is_the_hole(int index) {
return get(index) == GetHeap()->the_hole_value();
}
@@ -2186,20 +2143,13 @@ int64_t FixedDoubleArray::get_representation(int index) {
return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
}
-MaybeObject* FixedDoubleArray::get(int index) {
- if (is_the_hole(index)) {
- return GetHeap()->the_hole_value();
- } else {
- return GetHeap()->NumberFromDouble(get_scalar(index));
- }
-}
-
-Handle<Object> FixedDoubleArray::get_as_handle(int index) {
- if (is_the_hole(index)) {
- return GetIsolate()->factory()->the_hole_value();
+Handle<Object> FixedDoubleArray::get(Handle<FixedDoubleArray> array,
+ int index) {
+ if (array->is_the_hole(index)) {
+ return array->GetIsolate()->factory()->the_hole_value();
} else {
- return GetIsolate()->factory()->NewNumber(get_scalar(index));
+ return array->GetIsolate()->factory()->NewNumber(array->get_scalar(index));
}
}
@@ -2227,12 +2177,30 @@ bool FixedDoubleArray::is_the_hole(int index) {
}
-SMI_ACCESSORS(
- ConstantPoolArray, first_code_ptr_index, kFirstCodePointerIndexOffset)
-SMI_ACCESSORS(
- ConstantPoolArray, first_heap_ptr_index, kFirstHeapPointerIndexOffset)
-SMI_ACCESSORS(
- ConstantPoolArray, first_int32_index, kFirstInt32IndexOffset)
+double* FixedDoubleArray::data_start() {
+ return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize));
+}
+
+
+void FixedDoubleArray::FillWithHoles(int from, int to) {
+ for (int i = from; i < to; i++) {
+ set_the_hole(i);
+ }
+}
+
+
+void ConstantPoolArray::set_weak_object_state(
+ ConstantPoolArray::WeakObjectState state) {
+ int old_layout_field = READ_INT_FIELD(this, kArrayLayoutOffset);
+ int new_layout_field = WeakObjectStateField::update(old_layout_field, state);
+ WRITE_INT_FIELD(this, kArrayLayoutOffset, new_layout_field);
+}
+
+
+ConstantPoolArray::WeakObjectState ConstantPoolArray::get_weak_object_state() {
+ int layout_field = READ_INT_FIELD(this, kArrayLayoutOffset);
+ return WeakObjectStateField::decode(layout_field);
+}
int ConstantPoolArray::first_int64_index() {
@@ -2240,6 +2208,27 @@ int ConstantPoolArray::first_int64_index() {
}
+int ConstantPoolArray::first_code_ptr_index() {
+ int layout_field = READ_INT_FIELD(this, kArrayLayoutOffset);
+ return first_int64_index() +
+ NumberOfInt64EntriesField::decode(layout_field);
+}
+
+
+int ConstantPoolArray::first_heap_ptr_index() {
+ int layout_field = READ_INT_FIELD(this, kArrayLayoutOffset);
+ return first_code_ptr_index() +
+ NumberOfCodePtrEntriesField::decode(layout_field);
+}
+
+
+int ConstantPoolArray::first_int32_index() {
+ int layout_field = READ_INT_FIELD(this, kArrayLayoutOffset);
+ return first_heap_ptr_index() +
+ NumberOfHeapPtrEntriesField::decode(layout_field);
+}
+
+
int ConstantPoolArray::count_of_int64_entries() {
return first_code_ptr_index();
}
@@ -2260,18 +2249,20 @@ int ConstantPoolArray::count_of_int32_entries() {
}
-void ConstantPoolArray::SetEntryCounts(int number_of_int64_entries,
- int number_of_code_ptr_entries,
- int number_of_heap_ptr_entries,
- int number_of_int32_entries) {
- int current_index = number_of_int64_entries;
- set_first_code_ptr_index(current_index);
- current_index += number_of_code_ptr_entries;
- set_first_heap_ptr_index(current_index);
- current_index += number_of_heap_ptr_entries;
- set_first_int32_index(current_index);
- current_index += number_of_int32_entries;
- set_length(current_index);
+void ConstantPoolArray::Init(int number_of_int64_entries,
+ int number_of_code_ptr_entries,
+ int number_of_heap_ptr_entries,
+ int number_of_int32_entries) {
+ set_length(number_of_int64_entries +
+ number_of_code_ptr_entries +
+ number_of_heap_ptr_entries +
+ number_of_int32_entries);
+ int layout_field =
+ NumberOfInt64EntriesField::encode(number_of_int64_entries) |
+ NumberOfCodePtrEntriesField::encode(number_of_code_ptr_entries) |
+ NumberOfHeapPtrEntriesField::encode(number_of_heap_ptr_entries) |
+ WeakObjectStateField::encode(NO_WEAK_OBJECTS);
+ WRITE_INT_FIELD(this, kArrayLayoutOffset, layout_field);
}
@@ -2420,8 +2411,10 @@ void FixedArray::set_the_hole(int index) {
}
-double* FixedDoubleArray::data_start() {
- return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize));
+void FixedArray::FillWithHoles(int from, int to) {
+ for (int i = from; i < to; i++) {
+ set_the_hole(i);
+ }
}
@@ -2570,15 +2563,30 @@ void Map::LookupDescriptor(JSObject* holder,
void Map::LookupTransition(JSObject* holder,
Name* name,
LookupResult* result) {
- if (HasTransitionArray()) {
- TransitionArray* transition_array = transitions();
- int number = transition_array->Search(name);
- if (number != TransitionArray::kNotFound) {
- return result->TransitionResult(
- holder, transition_array->GetTarget(number));
- }
+ int transition_index = this->SearchTransition(name);
+ if (transition_index == TransitionArray::kNotFound) return result->NotFound();
+ result->TransitionResult(holder, this->GetTransition(transition_index));
+}
+
+
+FixedArrayBase* Map::GetInitialElements() {
+ if (has_fast_smi_or_object_elements() ||
+ has_fast_double_elements()) {
+ ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
+ return GetHeap()->empty_fixed_array();
+ } else if (has_external_array_elements()) {
+ ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(this);
+ ASSERT(!GetHeap()->InNewSpace(empty_array));
+ return empty_array;
+ } else if (has_fixed_typed_array_elements()) {
+ FixedTypedArrayBase* empty_array =
+ GetHeap()->EmptyFixedTypedArrayForMap(this);
+ ASSERT(!GetHeap()->InNewSpace(empty_array));
+ return empty_array;
+ } else {
+ UNREACHABLE();
}
- result->NotFound();
+ return NULL;
}
@@ -2629,14 +2637,6 @@ void DescriptorArray::SetRepresentation(int descriptor_index,
}
-void DescriptorArray::InitializeRepresentations(Representation representation) {
- int length = number_of_descriptors();
- for (int i = 0; i < length; i++) {
- SetRepresentation(i, representation);
- }
-}
-
-
Object** DescriptorArray::GetValueSlot(int descriptor_number) {
ASSERT(descriptor_number < number_of_descriptors());
return RawFieldOfElementAt(ToValueIndex(descriptor_number));
@@ -2649,6 +2649,11 @@ Object* DescriptorArray::GetValue(int descriptor_number) {
}
+void DescriptorArray::SetValue(int descriptor_index, Object* value) {
+ set(ToValueIndex(descriptor_index), value);
+}
+
+
PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
ASSERT(descriptor_number < number_of_descriptors());
Object* details = get(ToDetailsIndex(descriptor_number));
@@ -2667,6 +2672,12 @@ int DescriptorArray::GetFieldIndex(int descriptor_number) {
}
+HeapType* DescriptorArray::GetFieldType(int descriptor_number) {
+ ASSERT(GetDetails(descriptor_number).type() == FIELD);
+ return HeapType::cast(GetValue(descriptor_number));
+}
+
+
Object* DescriptorArray::GetConstant(int descriptor_number) {
return GetValue(descriptor_number);
}
@@ -2686,8 +2697,8 @@ AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
- desc->Init(GetKey(descriptor_number),
- GetValue(descriptor_number),
+ desc->Init(handle(GetKey(descriptor_number), GetIsolate()),
+ handle(GetValue(descriptor_number), GetIsolate()),
GetDetails(descriptor_number));
}
@@ -2700,10 +2711,10 @@ void DescriptorArray::Set(int descriptor_number,
NoIncrementalWriteBarrierSet(this,
ToKeyIndex(descriptor_number),
- desc->GetKey());
+ *desc->GetKey());
NoIncrementalWriteBarrierSet(this,
ToValueIndex(descriptor_number),
- desc->GetValue());
+ *desc->GetValue());
NoIncrementalWriteBarrierSet(this,
ToDetailsIndex(descriptor_number),
desc->GetDetails().AsSmi());
@@ -2714,14 +2725,15 @@ void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
// Range check.
ASSERT(descriptor_number < number_of_descriptors());
- set(ToKeyIndex(descriptor_number), desc->GetKey());
- set(ToValueIndex(descriptor_number), desc->GetValue());
+ set(ToKeyIndex(descriptor_number), *desc->GetKey());
+ set(ToValueIndex(descriptor_number), *desc->GetValue());
set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
}
void DescriptorArray::Append(Descriptor* desc,
const WhitenessWitness& witness) {
+ DisallowHeapAllocation no_gc;
int descriptor_number = number_of_descriptors();
SetNumberOfDescriptors(descriptor_number + 1);
Set(descriptor_number, desc, witness);
@@ -2741,6 +2753,7 @@ void DescriptorArray::Append(Descriptor* desc,
void DescriptorArray::Append(Descriptor* desc) {
+ DisallowHeapAllocation no_gc;
int descriptor_number = number_of_descriptors();
SetNumberOfDescriptors(descriptor_number + 1);
Set(descriptor_number, desc);
@@ -2766,7 +2779,7 @@ void DescriptorArray::SwapSortedKeys(int first, int second) {
}
-DescriptorArray::WhitenessWitness::WhitenessWitness(FixedArray* array)
+DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
: marking_(array->GetHeap()->incremental_marking()) {
marking_->EnterNoMarkingScope();
ASSERT(!marking_->IsMarking() ||
@@ -2779,8 +2792,8 @@ DescriptorArray::WhitenessWitness::~WhitenessWitness() {
}
-template<typename Shape, typename Key>
-int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
+template<typename Derived, typename Shape, typename Key>
+int HashTable<Derived, Shape, Key>::ComputeCapacity(int at_least_space_for) {
const int kMinCapacity = 32;
int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
if (capacity < kMinCapacity) {
@@ -2790,17 +2803,17 @@ int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
}
-template<typename Shape, typename Key>
-int HashTable<Shape, Key>::FindEntry(Key key) {
+template<typename Derived, typename Shape, typename Key>
+int HashTable<Derived, Shape, Key>::FindEntry(Key key) {
return FindEntry(GetIsolate(), key);
}
// Find entry for key otherwise return kNotFound.
-template<typename Shape, typename Key>
-int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
+template<typename Derived, typename Shape, typename Key>
+int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key) {
uint32_t capacity = Capacity();
- uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
+ uint32_t entry = FirstProbe(HashTable::Hash(key), capacity);
uint32_t count = 1;
// EnsureCapacity will guarantee the hash table is never full.
while (true) {
@@ -2893,6 +2906,8 @@ CAST_ACCESSOR(JSProxy)
CAST_ACCESSOR(JSFunctionProxy)
CAST_ACCESSOR(JSSet)
CAST_ACCESSOR(JSMap)
+CAST_ACCESSOR(JSSetIterator)
+CAST_ACCESSOR(JSMapIterator)
CAST_ACCESSOR(JSWeakMap)
CAST_ACCESSOR(JSWeakSet)
CAST_ACCESSOR(Foreign)
@@ -2925,17 +2940,22 @@ FixedTypedArray<Traits>* FixedTypedArray<Traits>::cast(Object* object) {
#undef MAKE_STRUCT_CAST
-template <typename Shape, typename Key>
-HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
+template <typename Derived, typename Shape, typename Key>
+HashTable<Derived, Shape, Key>*
+HashTable<Derived, Shape, Key>::cast(Object* obj) {
ASSERT(obj->IsHashTable());
return reinterpret_cast<HashTable*>(obj);
}
SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
+SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
+
SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
+NOBARRIER_SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
SMI_ACCESSORS(String, length, kLengthOffset)
+SYNCHRONIZED_SMI_ACCESSORS(String, length, kLengthOffset)
uint32_t Name::hash_field() {
@@ -2961,6 +2981,17 @@ bool Name::Equals(Name* other) {
}
+bool Name::Equals(Handle<Name> one, Handle<Name> two) {
+ if (one.is_identical_to(two)) return true;
+ if ((one->IsInternalizedString() && two->IsInternalizedString()) ||
+ one->IsSymbol() || two->IsSymbol()) {
+ return false;
+ }
+ return String::SlowEquals(Handle<String>::cast(one),
+ Handle<String>::cast(two));
+}
+
+
ACCESSORS(Symbol, name, Object, kNameOffset)
ACCESSORS(Symbol, flags, Smi, kFlagsOffset)
BOOL_ACCESSORS(Symbol, flags, is_private, kPrivateBit)
@@ -2975,19 +3006,20 @@ bool String::Equals(String* other) {
}
-MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
- if (!StringShape(this).IsCons()) return this;
- ConsString* cons = ConsString::cast(this);
- if (cons->IsFlat()) return cons->first();
- return SlowTryFlatten(pretenure);
+bool String::Equals(Handle<String> one, Handle<String> two) {
+ if (one.is_identical_to(two)) return true;
+ if (one->IsInternalizedString() && two->IsInternalizedString()) {
+ return false;
+ }
+ return SlowEquals(one, two);
}
-String* String::TryFlattenGetString(PretenureFlag pretenure) {
- MaybeObject* flat = TryFlatten(pretenure);
- Object* successfully_flattened;
- if (!flat->ToObject(&successfully_flattened)) return this;
- return String::cast(successfully_flattened);
+Handle<String> String::Flatten(Handle<String> string, PretenureFlag pretenure) {
+ if (!string->IsConsString()) return string;
+ Handle<ConsString> cons = Handle<ConsString>::cast(string);
+ if (cons->IsFlat()) return handle(cons->first());
+ return SlowFlatten(cons, pretenure);
}
@@ -3044,96 +3076,60 @@ String* String::GetUnderlying() {
}
-template<class Visitor, class ConsOp>
-void String::Visit(
- String* string,
- unsigned offset,
- Visitor& visitor,
- ConsOp& cons_op,
- int32_t type,
- unsigned length) {
- ASSERT(length == static_cast<unsigned>(string->length()));
+template<class Visitor>
+ConsString* String::VisitFlat(Visitor* visitor,
+ String* string,
+ const int offset) {
+ int slice_offset = offset;
+ const int length = string->length();
ASSERT(offset <= length);
- unsigned slice_offset = offset;
while (true) {
- ASSERT(type == string->map()->instance_type());
-
+ int32_t type = string->map()->instance_type();
switch (type & (kStringRepresentationMask | kStringEncodingMask)) {
case kSeqStringTag | kOneByteStringTag:
- visitor.VisitOneByteString(
+ visitor->VisitOneByteString(
SeqOneByteString::cast(string)->GetChars() + slice_offset,
length - offset);
- return;
+ return NULL;
case kSeqStringTag | kTwoByteStringTag:
- visitor.VisitTwoByteString(
+ visitor->VisitTwoByteString(
SeqTwoByteString::cast(string)->GetChars() + slice_offset,
length - offset);
- return;
+ return NULL;
case kExternalStringTag | kOneByteStringTag:
- visitor.VisitOneByteString(
+ visitor->VisitOneByteString(
ExternalAsciiString::cast(string)->GetChars() + slice_offset,
length - offset);
- return;
+ return NULL;
case kExternalStringTag | kTwoByteStringTag:
- visitor.VisitTwoByteString(
+ visitor->VisitTwoByteString(
ExternalTwoByteString::cast(string)->GetChars() + slice_offset,
length - offset);
- return;
+ return NULL;
case kSlicedStringTag | kOneByteStringTag:
case kSlicedStringTag | kTwoByteStringTag: {
SlicedString* slicedString = SlicedString::cast(string);
slice_offset += slicedString->offset();
string = slicedString->parent();
- type = string->map()->instance_type();
continue;
}
case kConsStringTag | kOneByteStringTag:
case kConsStringTag | kTwoByteStringTag:
- string = cons_op.Operate(string, &offset, &type, &length);
- if (string == NULL) return;
- slice_offset = offset;
- ASSERT(length == static_cast<unsigned>(string->length()));
- continue;
+ return ConsString::cast(string);
default:
UNREACHABLE();
- return;
+ return NULL;
}
}
}
-// TODO(dcarney): Remove this class after conversion to VisitFlat.
-class ConsStringCaptureOp {
- public:
- inline ConsStringCaptureOp() : cons_string_(NULL) {}
- inline String* Operate(String* string, unsigned*, int32_t*, unsigned*) {
- cons_string_ = ConsString::cast(string);
- return NULL;
- }
- ConsString* cons_string_;
-};
-
-
-template<class Visitor>
-ConsString* String::VisitFlat(Visitor* visitor,
- String* string,
- int offset,
- int length,
- int32_t type) {
- ASSERT(length >= 0 && length == string->length());
- ASSERT(offset >= 0 && offset <= length);
- ConsStringCaptureOp op;
- Visit(string, offset, *visitor, op, type, static_cast<unsigned>(length));
- return op.cons_string_;
-}
-
-
uint16_t SeqOneByteString::SeqOneByteStringGet(int index) {
ASSERT(index >= 0 && index < length());
return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
@@ -3313,12 +3309,7 @@ const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
}
-String* ConsStringNullOp::Operate(String*, unsigned*, int32_t*, unsigned*) {
- return NULL;
-}
-
-
-unsigned ConsStringIteratorOp::OffsetForDepth(unsigned depth) {
+int ConsStringIteratorOp::OffsetForDepth(int depth) {
return depth & kDepthMask;
}
@@ -3346,45 +3337,9 @@ void ConsStringIteratorOp::Pop() {
}
-bool ConsStringIteratorOp::HasMore() {
- return depth_ != 0;
-}
-
-
-void ConsStringIteratorOp::Reset() {
- depth_ = 0;
-}
-
-
-String* ConsStringIteratorOp::ContinueOperation(int32_t* type_out,
- unsigned* length_out) {
- bool blew_stack = false;
- String* string = NextLeaf(&blew_stack, type_out, length_out);
- // String found.
- if (string != NULL) {
- // Verify output.
- ASSERT(*length_out == static_cast<unsigned>(string->length()));
- ASSERT(*type_out == string->map()->instance_type());
- return string;
- }
- // Traversal complete.
- if (!blew_stack) return NULL;
- // Restart search from root.
- unsigned offset_out;
- string = Search(&offset_out, type_out, length_out);
- // Verify output.
- ASSERT(string == NULL || offset_out == 0);
- ASSERT(string == NULL ||
- *length_out == static_cast<unsigned>(string->length()));
- ASSERT(string == NULL || *type_out == string->map()->instance_type());
- return string;
-}
-
-
uint16_t StringCharacterStream::GetNext() {
ASSERT(buffer8_ != NULL && end_ != NULL);
// Advance cursor if needed.
- // TODO(dcarney): Ensure uses of the api call HasMore first and avoid this.
if (buffer8_ == end_) HasMore();
ASSERT(buffer8_ < end_);
return is_one_byte_ ? *buffer8_++ : *buffer16_++;
@@ -3393,41 +3348,39 @@ uint16_t StringCharacterStream::GetNext() {
StringCharacterStream::StringCharacterStream(String* string,
ConsStringIteratorOp* op,
- unsigned offset)
+ int offset)
: is_one_byte_(false),
op_(op) {
Reset(string, offset);
}
-void StringCharacterStream::Reset(String* string, unsigned offset) {
- op_->Reset();
+void StringCharacterStream::Reset(String* string, int offset) {
buffer8_ = NULL;
end_ = NULL;
- int32_t type = string->map()->instance_type();
- unsigned length = string->length();
- String::Visit(string, offset, *this, *op_, type, length);
+ ConsString* cons_string = String::VisitFlat(this, string, offset);
+ op_->Reset(cons_string, offset);
+ if (cons_string != NULL) {
+ string = op_->Next(&offset);
+ if (string != NULL) String::VisitFlat(this, string, offset);
+ }
}
bool StringCharacterStream::HasMore() {
if (buffer8_ != end_) return true;
- if (!op_->HasMore()) return false;
- unsigned length;
- int32_t type;
- String* string = op_->ContinueOperation(&type, &length);
+ int offset;
+ String* string = op_->Next(&offset);
+ ASSERT_EQ(offset, 0);
if (string == NULL) return false;
- ASSERT(!string->IsConsString());
- ASSERT(string->length() != 0);
- ConsStringNullOp null_op;
- String::Visit(string, 0, *this, null_op, type, length);
+ String::VisitFlat(this, string);
ASSERT(buffer8_ != end_);
return true;
}
void StringCharacterStream::VisitOneByteString(
- const uint8_t* chars, unsigned length) {
+ const uint8_t* chars, int length) {
is_one_byte_ = true;
buffer8_ = chars;
end_ = chars + length;
@@ -3435,7 +3388,7 @@ void StringCharacterStream::VisitOneByteString(
void StringCharacterStream::VisitTwoByteString(
- const uint16_t* chars, unsigned length) {
+ const uint16_t* chars, int length) {
is_one_byte_ = false;
buffer16_ = chars;
end_ = reinterpret_cast<const uint8_t*>(chars + length);
@@ -3519,8 +3472,11 @@ uint8_t ExternalUint8ClampedArray::get_scalar(int index) {
}
-MaybeObject* ExternalUint8ClampedArray::get(int index) {
- return Smi::FromInt(static_cast<int>(get_scalar(index)));
+Handle<Object> ExternalUint8ClampedArray::get(
+ Handle<ExternalUint8ClampedArray> array,
+ int index) {
+ return Handle<Smi>(Smi::FromInt(array->get_scalar(index)),
+ array->GetIsolate());
}
@@ -3550,8 +3506,10 @@ int8_t ExternalInt8Array::get_scalar(int index) {
}
-MaybeObject* ExternalInt8Array::get(int index) {
- return Smi::FromInt(static_cast<int>(get_scalar(index)));
+Handle<Object> ExternalInt8Array::get(Handle<ExternalInt8Array> array,
+ int index) {
+ return Handle<Smi>(Smi::FromInt(array->get_scalar(index)),
+ array->GetIsolate());
}
@@ -3569,8 +3527,10 @@ uint8_t ExternalUint8Array::get_scalar(int index) {
}
-MaybeObject* ExternalUint8Array::get(int index) {
- return Smi::FromInt(static_cast<int>(get_scalar(index)));
+Handle<Object> ExternalUint8Array::get(Handle<ExternalUint8Array> array,
+ int index) {
+ return Handle<Smi>(Smi::FromInt(array->get_scalar(index)),
+ array->GetIsolate());
}
@@ -3588,8 +3548,10 @@ int16_t ExternalInt16Array::get_scalar(int index) {
}
-MaybeObject* ExternalInt16Array::get(int index) {
- return Smi::FromInt(static_cast<int>(get_scalar(index)));
+Handle<Object> ExternalInt16Array::get(Handle<ExternalInt16Array> array,
+ int index) {
+ return Handle<Smi>(Smi::FromInt(array->get_scalar(index)),
+ array->GetIsolate());
}
@@ -3607,8 +3569,10 @@ uint16_t ExternalUint16Array::get_scalar(int index) {
}
-MaybeObject* ExternalUint16Array::get(int index) {
- return Smi::FromInt(static_cast<int>(get_scalar(index)));
+Handle<Object> ExternalUint16Array::get(Handle<ExternalUint16Array> array,
+ int index) {
+ return Handle<Smi>(Smi::FromInt(array->get_scalar(index)),
+ array->GetIsolate());
}
@@ -3626,8 +3590,10 @@ int32_t ExternalInt32Array::get_scalar(int index) {
}
-MaybeObject* ExternalInt32Array::get(int index) {
- return GetHeap()->NumberFromInt32(get_scalar(index));
+Handle<Object> ExternalInt32Array::get(Handle<ExternalInt32Array> array,
+ int index) {
+ return array->GetIsolate()->factory()->
+ NewNumberFromInt(array->get_scalar(index));
}
@@ -3645,8 +3611,10 @@ uint32_t ExternalUint32Array::get_scalar(int index) {
}
-MaybeObject* ExternalUint32Array::get(int index) {
- return GetHeap()->NumberFromUint32(get_scalar(index));
+Handle<Object> ExternalUint32Array::get(Handle<ExternalUint32Array> array,
+ int index) {
+ return array->GetIsolate()->factory()->
+ NewNumberFromUint(array->get_scalar(index));
}
@@ -3664,8 +3632,9 @@ float ExternalFloat32Array::get_scalar(int index) {
}
-MaybeObject* ExternalFloat32Array::get(int index) {
- return GetHeap()->NumberFromDouble(get_scalar(index));
+Handle<Object> ExternalFloat32Array::get(Handle<ExternalFloat32Array> array,
+ int index) {
+ return array->GetIsolate()->factory()->NewNumber(array->get_scalar(index));
}
@@ -3683,8 +3652,9 @@ double ExternalFloat64Array::get_scalar(int index) {
}
-MaybeObject* ExternalFloat64Array::get(int index) {
- return GetHeap()->NumberFromDouble(get_scalar(index));
+Handle<Object> ExternalFloat64Array::get(Handle<ExternalFloat64Array> array,
+ int index) {
+ return array->GetIsolate()->factory()->NewNumber(array->get_scalar(index));
}
@@ -3829,83 +3799,80 @@ double FixedTypedArray<Float64ArrayTraits>::from_double(double value) {
template <class Traits>
-MaybeObject* FixedTypedArray<Traits>::get(int index) {
- return Traits::ToObject(GetHeap(), get_scalar(index));
+Handle<Object> FixedTypedArray<Traits>::get(
+ Handle<FixedTypedArray<Traits> > array,
+ int index) {
+ return Traits::ToHandle(array->GetIsolate(), array->get_scalar(index));
}
+
template <class Traits>
-MaybeObject* FixedTypedArray<Traits>::SetValue(uint32_t index, Object* value) {
+Handle<Object> FixedTypedArray<Traits>::SetValue(
+ Handle<FixedTypedArray<Traits> > array,
+ uint32_t index,
+ Handle<Object> value) {
ElementType cast_value = Traits::defaultValue();
- if (index < static_cast<uint32_t>(length())) {
+ if (index < static_cast<uint32_t>(array->length())) {
if (value->IsSmi()) {
- int int_value = Smi::cast(value)->value();
+ int int_value = Handle<Smi>::cast(value)->value();
cast_value = from_int(int_value);
} else if (value->IsHeapNumber()) {
- double double_value = HeapNumber::cast(value)->value();
+ double double_value = Handle<HeapNumber>::cast(value)->value();
cast_value = from_double(double_value);
} else {
// Clamp undefined to the default value. All other types have been
// converted to a number type further up in the call chain.
ASSERT(value->IsUndefined());
}
- set(index, cast_value);
+ array->set(index, cast_value);
}
- return Traits::ToObject(GetHeap(), cast_value);
-}
-
-template <class Traits>
-Handle<Object> FixedTypedArray<Traits>::SetValue(
- Handle<FixedTypedArray<Traits> > array,
- uint32_t index,
- Handle<Object> value) {
- CALL_HEAP_FUNCTION(array->GetIsolate(),
- array->SetValue(index, *value),
- Object);
+ return Traits::ToHandle(array->GetIsolate(), cast_value);
}
-MaybeObject* Uint8ArrayTraits::ToObject(Heap*, uint8_t scalar) {
- return Smi::FromInt(scalar);
+Handle<Object> Uint8ArrayTraits::ToHandle(Isolate* isolate, uint8_t scalar) {
+ return handle(Smi::FromInt(scalar), isolate);
}
-MaybeObject* Uint8ClampedArrayTraits::ToObject(Heap*, uint8_t scalar) {
- return Smi::FromInt(scalar);
+Handle<Object> Uint8ClampedArrayTraits::ToHandle(Isolate* isolate,
+ uint8_t scalar) {
+ return handle(Smi::FromInt(scalar), isolate);
}
-MaybeObject* Int8ArrayTraits::ToObject(Heap*, int8_t scalar) {
- return Smi::FromInt(scalar);
+Handle<Object> Int8ArrayTraits::ToHandle(Isolate* isolate, int8_t scalar) {
+ return handle(Smi::FromInt(scalar), isolate);
}
-MaybeObject* Uint16ArrayTraits::ToObject(Heap*, uint16_t scalar) {
- return Smi::FromInt(scalar);
+Handle<Object> Uint16ArrayTraits::ToHandle(Isolate* isolate, uint16_t scalar) {
+ return handle(Smi::FromInt(scalar), isolate);
}
-MaybeObject* Int16ArrayTraits::ToObject(Heap*, int16_t scalar) {
- return Smi::FromInt(scalar);
+Handle<Object> Int16ArrayTraits::ToHandle(Isolate* isolate, int16_t scalar) {
+ return handle(Smi::FromInt(scalar), isolate);
}
-MaybeObject* Uint32ArrayTraits::ToObject(Heap* heap, uint32_t scalar) {
- return heap->NumberFromUint32(scalar);
+Handle<Object> Uint32ArrayTraits::ToHandle(Isolate* isolate, uint32_t scalar) {
+ return isolate->factory()->NewNumberFromUint(scalar);
}
-MaybeObject* Int32ArrayTraits::ToObject(Heap* heap, int32_t scalar) {
- return heap->NumberFromInt32(scalar);
+Handle<Object> Int32ArrayTraits::ToHandle(Isolate* isolate, int32_t scalar) {
+ return isolate->factory()->NewNumberFromInt(scalar);
}
-MaybeObject* Float32ArrayTraits::ToObject(Heap* heap, float scalar) {
- return heap->NumberFromDouble(scalar);
+Handle<Object> Float32ArrayTraits::ToHandle(Isolate* isolate, float scalar) {
+ return isolate->factory()->NewNumber(scalar);
}
-MaybeObject* Float64ArrayTraits::ToObject(Heap* heap, double scalar) {
- return heap->NumberFromDouble(scalar);
+Handle<Object> Float64ArrayTraits::ToHandle(Isolate* isolate, double scalar) {
+ return isolate->factory()->NewNumber(scalar);
}
@@ -3921,7 +3888,8 @@ void Map::set_visitor_id(int id) {
int Map::instance_size() {
- return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
+ return NOBARRIER_READ_BYTE_FIELD(
+ this, kInstanceSizeOffset) << kPointerSizeLog2;
}
@@ -3960,7 +3928,7 @@ int HeapObject::SizeFromMap(Map* map) {
return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
}
if (instance_type == FREE_SPACE_TYPE) {
- return reinterpret_cast<FreeSpace*>(this)->size();
+ return reinterpret_cast<FreeSpace*>(this)->nobarrier_size();
}
if (instance_type == STRING_TYPE ||
instance_type == INTERNALIZED_STRING_TYPE) {
@@ -3991,7 +3959,8 @@ void Map::set_instance_size(int value) {
ASSERT_EQ(0, value & (kPointerSize - 1));
value >>= kPointerSizeLog2;
ASSERT(0 <= value && value < 256);
- WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
+ NOBARRIER_WRITE_BYTE_FIELD(
+ this, kInstanceSizeOffset, static_cast<byte>(value));
}
@@ -4377,6 +4346,7 @@ bool Code::has_major_key() {
kind() == LOAD_IC ||
kind() == KEYED_LOAD_IC ||
kind() == STORE_IC ||
+ kind() == CALL_IC ||
kind() == KEYED_STORE_IC ||
kind() == TO_BOOLEAN_IC;
}
@@ -4559,12 +4529,41 @@ bool Code::marked_for_deoptimization() {
void Code::set_marked_for_deoptimization(bool flag) {
ASSERT(kind() == OPTIMIZED_FUNCTION);
+ ASSERT(!flag || AllowDeoptimization::IsAllowed(GetIsolate()));
int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
int updated = MarkedForDeoptimizationField::update(previous, flag);
WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
}
+bool Code::is_weak_stub() {
+ return CanBeWeakStub() && WeakStubField::decode(
+ READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
+}
+
+
+void Code::mark_as_weak_stub() {
+ ASSERT(CanBeWeakStub());
+ int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
+ int updated = WeakStubField::update(previous, true);
+ WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
+}
+
+
+bool Code::is_invalidated_weak_stub() {
+ return is_weak_stub() && InvalidatedWeakStubField::decode(
+ READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
+}
+
+
+void Code::mark_as_invalidated_weak_stub() {
+ ASSERT(is_inline_cache_stub());
+ int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
+ int updated = InvalidatedWeakStubField::update(previous, true);
+ WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
+}
+
+
bool Code::is_inline_cache_stub() {
Kind kind = this->kind();
switch (kind) {
@@ -4677,10 +4676,9 @@ Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
bool Code::IsWeakObjectInOptimizedCode(Object* object) {
- ASSERT(is_optimized_code());
+ if (!FLAG_collect_maps) return false;
if (object->IsMap()) {
return Map::cast(object)->CanTransition() &&
- FLAG_collect_maps &&
FLAG_weak_embedded_maps_in_optimized_code;
}
if (object->IsJSObject() ||
@@ -4709,6 +4707,13 @@ class Code::FindAndReplacePattern {
};
+bool Code::IsWeakObjectInIC(Object* object) {
+ return object->IsMap() && Map::cast(object)->CanTransition() &&
+ FLAG_collect_maps &&
+ FLAG_weak_embedded_maps_in_ic;
+}
+
+
Object* Map::prototype() {
return READ_FIELD(this, kPrototypeOffset);
}
@@ -4723,21 +4728,17 @@ void Map::set_prototype(Object* value, WriteBarrierMode mode) {
// If the descriptor is using the empty transition array, install a new empty
// transition array that will have place for an element transition.
-static MaybeObject* EnsureHasTransitionArray(Map* map) {
- TransitionArray* transitions;
- MaybeObject* maybe_transitions;
+static void EnsureHasTransitionArray(Handle<Map> map) {
+ Handle<TransitionArray> transitions;
if (!map->HasTransitionArray()) {
- maybe_transitions = TransitionArray::Allocate(map->GetIsolate(), 0);
- if (!maybe_transitions->To(&transitions)) return maybe_transitions;
+ transitions = TransitionArray::Allocate(map->GetIsolate(), 0);
transitions->set_back_pointer_storage(map->GetBackPointer());
} else if (!map->transitions()->IsFullTransitionArray()) {
- maybe_transitions = map->transitions()->ExtendToFullTransitionArray();
- if (!maybe_transitions->To(&transitions)) return maybe_transitions;
+ transitions = TransitionArray::ExtendToFullTransitionArray(map);
} else {
- return map;
+ return;
}
- map->set_transitions(transitions);
- return transitions;
+ map->set_transitions(*transitions);
}
@@ -4765,25 +4766,11 @@ uint32_t Map::bit_field3() {
}
-void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) {
- Object* back_pointer = GetBackPointer();
-
- if (Heap::ShouldZapGarbage() && HasTransitionArray()) {
- ZapTransitions();
- }
-
- WRITE_FIELD(this, kTransitionsOrBackPointerOffset, back_pointer);
- CONDITIONAL_WRITE_BARRIER(
- heap, this, kTransitionsOrBackPointerOffset, back_pointer, mode);
-}
-
-
-void Map::AppendDescriptor(Descriptor* desc,
- const DescriptorArray::WhitenessWitness& witness) {
+void Map::AppendDescriptor(Descriptor* desc) {
DescriptorArray* descriptors = instance_descriptors();
int number_of_own_descriptors = NumberOfOwnDescriptors();
ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
- descriptors->Append(desc, witness);
+ descriptors->Append(desc);
SetNumberOfOwnDescriptors(number_of_own_descriptors + 1);
}
@@ -4824,33 +4811,14 @@ bool Map::CanHaveMoreTransitions() {
}
-MaybeObject* Map::AddTransition(Name* key,
- Map* target,
- SimpleTransitionFlag flag) {
- if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
- return TransitionArray::NewWith(flag, key, target, GetBackPointer());
-}
-
-
-void Map::SetTransition(int transition_index, Map* target) {
- transitions()->SetTarget(transition_index, target);
-}
-
-
Map* Map::GetTransition(int transition_index) {
return transitions()->GetTarget(transition_index);
}
-MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
- TransitionArray* transitions;
- MaybeObject* maybe_transitions = AddTransition(
- GetHeap()->elements_transition_symbol(),
- transitioned_map,
- FULL_TRANSITION);
- if (!maybe_transitions->To(&transitions)) return maybe_transitions;
- set_transitions(transitions);
- return transitions;
+int Map::SearchTransition(Name* name) {
+ if (HasTransitionArray()) return transitions()->Search(name);
+ return TransitionArray::kNotFound;
}
@@ -4863,19 +4831,18 @@ FixedArray* Map::GetPrototypeTransitions() {
}
-MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
- MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
- if (allow_prototype->IsFailure()) return allow_prototype;
- int old_number_of_transitions = NumberOfProtoTransitions();
+void Map::SetPrototypeTransitions(
+ Handle<Map> map, Handle<FixedArray> proto_transitions) {
+ EnsureHasTransitionArray(map);
+ int old_number_of_transitions = map->NumberOfProtoTransitions();
#ifdef DEBUG
- if (HasPrototypeTransitions()) {
- ASSERT(GetPrototypeTransitions() != proto_transitions);
- ZapPrototypeTransitions();
+ if (map->HasPrototypeTransitions()) {
+ ASSERT(map->GetPrototypeTransitions() != *proto_transitions);
+ map->ZapPrototypeTransitions();
}
#endif
- transitions()->SetPrototypeTransitions(proto_transitions);
- SetNumberOfProtoTransitions(old_number_of_transitions);
- return this;
+ map->transitions()->SetPrototypeTransitions(*proto_transitions);
+ map->SetNumberOfProtoTransitions(old_number_of_transitions);
}
@@ -4940,23 +4907,6 @@ void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
}
-// Can either be Smi (no transitions), normal transition array, or a transition
-// array with the header overwritten as a Smi (thus iterating).
-TransitionArray* Map::unchecked_transition_array() {
- Object* object = *HeapObject::RawField(this,
- Map::kTransitionsOrBackPointerOffset);
- TransitionArray* transition_array = static_cast<TransitionArray*>(object);
- return transition_array;
-}
-
-
-HeapObject* Map::UncheckedPrototypeTransitions() {
- ASSERT(HasTransitionArray());
- ASSERT(unchecked_transition_array()->HasPrototypeTransitions());
- return unchecked_transition_array()->UncheckedPrototypeTransitions();
-}
-
-
ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset)
ACCESSORS(Map, constructor, Object, kConstructorOffset)
@@ -4971,6 +4921,7 @@ ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
+ACCESSORS(JSGlobalProxy, hash, Object, kHashOffset)
ACCESSORS(AccessorInfo, name, Object, kNameOffset)
ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
@@ -5082,7 +5033,6 @@ void Script::set_compilation_state(CompilationState state) {
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
@@ -5092,12 +5042,13 @@ ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
-#endif
ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
kOptimizedCodeMapOffset)
ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
+ACCESSORS(SharedFunctionInfo, feedback_vector, FixedArray,
+ kFeedbackVectorOffset)
ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
kInstanceClassNameOffset)
@@ -5105,7 +5056,6 @@ ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
-SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
SMI_ACCESSORS(FunctionTemplateInfo, length, kLengthOffset)
@@ -5160,6 +5110,8 @@ SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
SMI_ACCESSORS(SharedFunctionInfo, opt_count_and_bailout_reason,
kOptCountAndBailoutReasonOffset)
SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
+SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
+SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset)
#else
@@ -5210,9 +5162,15 @@ PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
opt_count_and_bailout_reason,
kOptCountAndBailoutReasonOffset)
-
PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, counters, kCountersOffset)
+PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
+ ast_node_count,
+ kAstNodeCountOffset)
+PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
+ profiler_ticks,
+ kProfilerTicksOffset)
+
#endif
@@ -5256,12 +5214,6 @@ void SharedFunctionInfo::set_optimization_disabled(bool disable) {
}
-int SharedFunctionInfo::profiler_ticks() {
- if (code()->kind() != Code::FUNCTION) return 0;
- return code()->profiler_ticks();
-}
-
-
StrictMode SharedFunctionInfo::strict_mode() {
return BooleanBit::get(compiler_hints(), kStrictModeFunction)
? STRICT : SLOPPY;
@@ -5355,6 +5307,7 @@ void SharedFunctionInfo::ReplaceCode(Code* value) {
}
ASSERT(code()->gc_metadata() == NULL && value->gc_metadata() == NULL);
+
set_code(value);
}
@@ -5712,6 +5665,32 @@ void JSProxy::InitializeBody(int object_size, Object* value) {
ACCESSORS(JSSet, table, Object, kTableOffset)
ACCESSORS(JSMap, table, Object, kTableOffset)
+
+
+#define ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(name, type, offset) \
+ template<class Derived, class TableType> \
+ type* OrderedHashTableIterator<Derived, TableType>::name() { \
+ return type::cast(READ_FIELD(this, offset)); \
+ } \
+ template<class Derived, class TableType> \
+ void OrderedHashTableIterator<Derived, TableType>::set_##name( \
+ type* value, WriteBarrierMode mode) { \
+ WRITE_FIELD(this, offset, value); \
+ CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
+ }
+
+ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(table, Object, kTableOffset)
+ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(index, Smi, kIndexOffset)
+ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(count, Smi, kCountOffset)
+ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(kind, Smi, kKindOffset)
+ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(next_iterator, Object,
+ kNextIteratorOffset)
+ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(previous_iterator, Object,
+ kPreviousIteratorOffset)
+
+#undef ORDERED_HASH_TABLE_ITERATOR_ACCESSORS
+
+
ACCESSORS(JSWeakCollection, table, Object, kTableOffset)
ACCESSORS(JSWeakCollection, next, Object, kNextOffset)
@@ -5733,6 +5712,11 @@ SMI_ACCESSORS(JSGeneratorObject, continuation, kContinuationOffset)
ACCESSORS(JSGeneratorObject, operand_stack, FixedArray, kOperandStackOffset)
SMI_ACCESSORS(JSGeneratorObject, stack_handler_index, kStackHandlerIndexOffset)
+bool JSGeneratorObject::is_suspended() {
+ ASSERT_LT(kGeneratorExecuting, kGeneratorClosed);
+ ASSERT_EQ(kGeneratorClosed, 0);
+ return continuation() > 0;
+}
JSGeneratorObject* JSGeneratorObject::cast(Object* obj) {
ASSERT(obj->IsJSGeneratorObject());
@@ -5832,7 +5816,7 @@ void Code::set_type_feedback_info(Object* value, WriteBarrierMode mode) {
int Code::stub_info() {
ASSERT(kind() == COMPARE_IC || kind() == COMPARE_NIL_IC ||
- kind() == BINARY_OP_IC || kind() == LOAD_IC);
+ kind() == BINARY_OP_IC || kind() == LOAD_IC || kind() == CALL_IC);
return Smi::cast(raw_type_feedback_info())->value();
}
@@ -5843,6 +5827,7 @@ void Code::set_stub_info(int value) {
kind() == BINARY_OP_IC ||
kind() == STUB ||
kind() == LOAD_IC ||
+ kind() == CALL_IC ||
kind() == KEYED_LOAD_IC ||
kind() == STORE_IC ||
kind() == KEYED_STORE_IC);
@@ -6121,24 +6106,6 @@ bool JSObject::HasIndexedInterceptor() {
}
-MaybeObject* JSObject::EnsureWritableFastElements() {
- ASSERT(HasFastSmiOrObjectElements());
- FixedArray* elems = FixedArray::cast(elements());
- Isolate* isolate = GetIsolate();
- if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
- Object* writable_elems;
- { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
- elems, isolate->heap()->fixed_array_map());
- if (!maybe_writable_elems->ToObject(&writable_elems)) {
- return maybe_writable_elems;
- }
- }
- set_elements(FixedArray::cast(writable_elems));
- isolate->counters()->cow_arrays_converted()->Increment();
- return writable_elems;
-}
-
-
NameDictionary* JSObject::property_dictionary() {
ASSERT(!HasFastProperties());
return NameDictionary::cast(properties());
@@ -6151,6 +6118,20 @@ SeededNumberDictionary* JSObject::element_dictionary() {
}
+Handle<JSSetIterator> JSSetIterator::Create(
+ Handle<OrderedHashSet> table,
+ int kind) {
+ return CreateInternal(table->GetIsolate()->set_iterator_map(), table, kind);
+}
+
+
+Handle<JSMapIterator> JSMapIterator::Create(
+ Handle<OrderedHashMap> table,
+ int kind) {
+ return CreateInternal(table->GetIsolate()->map_iterator_map(), table, kind);
+}
+
+
bool Name::IsHashFieldComputed(uint32_t field) {
return (field & kHashNotComputedMask) == 0;
}
@@ -6461,27 +6442,27 @@ bool AccessorPair::prohibits_overwriting() {
}
-template<typename Shape, typename Key>
-void Dictionary<Shape, Key>::SetEntry(int entry,
- Object* key,
- Object* value) {
+template<typename Derived, typename Shape, typename Key>
+void Dictionary<Derived, Shape, Key>::SetEntry(int entry,
+ Handle<Object> key,
+ Handle<Object> value) {
SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
}
-template<typename Shape, typename Key>
-void Dictionary<Shape, Key>::SetEntry(int entry,
- Object* key,
- Object* value,
- PropertyDetails details) {
+template<typename Derived, typename Shape, typename Key>
+void Dictionary<Derived, Shape, Key>::SetEntry(int entry,
+ Handle<Object> key,
+ Handle<Object> value,
+ PropertyDetails details) {
ASSERT(!key->IsName() ||
details.IsDeleted() ||
details.dictionary_index() > 0);
- int index = HashTable<Shape, Key>::EntryToIndex(entry);
+ int index = DerivedHashTable::EntryToIndex(entry);
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
- FixedArray::set(index, key, mode);
- FixedArray::set(index+1, value, mode);
+ FixedArray::set(index, *key, mode);
+ FixedArray::set(index+1, *value, mode);
FixedArray::set(index+2, details.AsSmi());
}
@@ -6503,10 +6484,12 @@ uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
}
+
uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
return ComputeIntegerHash(key, seed);
}
+
uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
uint32_t seed,
Object* other) {
@@ -6514,12 +6497,13 @@ uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
}
-MaybeObject* NumberDictionaryShape::AsObject(Heap* heap, uint32_t key) {
- return heap->NumberFromUint32(key);
+
+Handle<Object> NumberDictionaryShape::AsHandle(Isolate* isolate, uint32_t key) {
+ return isolate->factory()->NewNumberFromUint(key);
}
-bool NameDictionaryShape::IsMatch(Name* key, Object* other) {
+bool NameDictionaryShape::IsMatch(Handle<Name> key, Object* other) {
// We know that all entries in a hash table had their hash keys created.
// Use that knowledge to have fast failure.
if (key->Hash() != Name::cast(other)->Hash()) return false;
@@ -6527,63 +6511,72 @@ bool NameDictionaryShape::IsMatch(Name* key, Object* other) {
}
-uint32_t NameDictionaryShape::Hash(Name* key) {
+uint32_t NameDictionaryShape::Hash(Handle<Name> key) {
return key->Hash();
}
-uint32_t NameDictionaryShape::HashForObject(Name* key, Object* other) {
+uint32_t NameDictionaryShape::HashForObject(Handle<Name> key, Object* other) {
return Name::cast(other)->Hash();
}
-MaybeObject* NameDictionaryShape::AsObject(Heap* heap, Name* key) {
+Handle<Object> NameDictionaryShape::AsHandle(Isolate* isolate,
+ Handle<Name> key) {
ASSERT(key->IsUniqueName());
return key;
}
-template <int entrysize>
-bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
+void NameDictionary::DoGenerateNewEnumerationIndices(
+ Handle<NameDictionary> dictionary) {
+ DerivedDictionary::GenerateNewEnumerationIndices(dictionary);
+}
+
+
+bool ObjectHashTableShape::IsMatch(Handle<Object> key, Object* other) {
return key->SameValue(other);
}
-template <int entrysize>
-uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
+uint32_t ObjectHashTableShape::Hash(Handle<Object> key) {
return Smi::cast(key->GetHash())->value();
}
-template <int entrysize>
-uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
- Object* other) {
+uint32_t ObjectHashTableShape::HashForObject(Handle<Object> key,
+ Object* other) {
return Smi::cast(other->GetHash())->value();
}
-template <int entrysize>
-MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Heap* heap,
- Object* key) {
+Handle<Object> ObjectHashTableShape::AsHandle(Isolate* isolate,
+ Handle<Object> key) {
return key;
}
+Handle<ObjectHashTable> ObjectHashTable::Shrink(
+ Handle<ObjectHashTable> table, Handle<Object> key) {
+ return DerivedHashTable::Shrink(table, key);
+}
+
+
template <int entrysize>
-bool WeakHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
+bool WeakHashTableShape<entrysize>::IsMatch(Handle<Object> key, Object* other) {
return key->SameValue(other);
}
template <int entrysize>
-uint32_t WeakHashTableShape<entrysize>::Hash(Object* key) {
- intptr_t hash = reinterpret_cast<intptr_t>(key);
+uint32_t WeakHashTableShape<entrysize>::Hash(Handle<Object> key) {
+ intptr_t hash = reinterpret_cast<intptr_t>(*key);
return (uint32_t)(hash & 0xFFFFFFFF);
}
template <int entrysize>
-uint32_t WeakHashTableShape<entrysize>::HashForObject(Object* key,
+uint32_t WeakHashTableShape<entrysize>::HashForObject(Handle<Object> key,
Object* other) {
intptr_t hash = reinterpret_cast<intptr_t>(other);
return (uint32_t)(hash & 0xFFFFFFFF);
@@ -6591,8 +6584,8 @@ uint32_t WeakHashTableShape<entrysize>::HashForObject(Object* key,
template <int entrysize>
-MaybeObject* WeakHashTableShape<entrysize>::AsObject(Heap* heap,
- Object* key) {
+Handle<Object> WeakHashTableShape<entrysize>::AsHandle(Isolate* isolate,
+ Handle<Object> key) {
return key;
}
@@ -6654,24 +6647,6 @@ void JSArray::SetContent(Handle<JSArray> array,
}
-MaybeObject* FixedArray::Copy() {
- if (length() == 0) return this;
- return GetHeap()->CopyFixedArray(this);
-}
-
-
-MaybeObject* FixedDoubleArray::Copy() {
- if (length() == 0) return this;
- return GetHeap()->CopyFixedDoubleArray(this);
-}
-
-
-MaybeObject* ConstantPoolArray::Copy() {
- if (length() == 0) return this;
- return GetHeap()->CopyConstantPoolArray(this);
-}
-
-
Handle<Object> TypeFeedbackInfo::UninitializedSentinel(Isolate* isolate) {
return isolate->factory()->uninitialized_symbol();
}
@@ -6771,10 +6746,6 @@ bool TypeFeedbackInfo::matches_inlined_type_change_checksum(int checksum) {
}
-ACCESSORS(TypeFeedbackInfo, feedback_vector, FixedArray,
- kFeedbackVectorOffset)
-
-
SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
@@ -6863,11 +6834,15 @@ void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
#undef ACCESSORS
#undef ACCESSORS_TO_SMI
#undef SMI_ACCESSORS
+#undef SYNCHRONIZED_SMI_ACCESSORS
+#undef NOBARRIER_SMI_ACCESSORS
#undef BOOL_GETTER
#undef BOOL_ACCESSORS
#undef FIELD_ADDR
#undef READ_FIELD
+#undef NOBARRIER_READ_FIELD
#undef WRITE_FIELD
+#undef NOBARRIER_WRITE_FIELD
#undef WRITE_BARRIER
#undef CONDITIONAL_WRITE_BARRIER
#undef READ_DOUBLE_FIELD
@@ -6882,6 +6857,8 @@ void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
#undef WRITE_SHORT_FIELD
#undef READ_BYTE_FIELD
#undef WRITE_BYTE_FIELD
+#undef NOBARRIER_READ_BYTE_FIELD
+#undef NOBARRIER_WRITE_BYTE_FIELD
} } // namespace v8::internal
diff --git a/deps/v8/src/objects-printer.cc b/deps/v8/src/objects-printer.cc
index 518167cc51..4fb5b56764 100644
--- a/deps/v8/src/objects-printer.cc
+++ b/deps/v8/src/objects-printer.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -37,32 +14,27 @@ namespace internal {
#ifdef OBJECT_PRINT
-void MaybeObject::Print() {
+void Object::Print() {
Print(stdout);
}
-void MaybeObject::Print(FILE* out) {
- Object* this_as_object;
- if (ToObject(&this_as_object)) {
- if (this_as_object->IsSmi()) {
- Smi::cast(this_as_object)->SmiPrint(out);
- } else {
- HeapObject::cast(this_as_object)->HeapObjectPrint(out);
- }
+void Object::Print(FILE* out) {
+ if (IsSmi()) {
+ Smi::cast(this)->SmiPrint(out);
} else {
- Failure::cast(this)->FailurePrint(out);
+ HeapObject::cast(this)->HeapObjectPrint(out);
}
Flush(out);
}
-void MaybeObject::PrintLn() {
+void Object::PrintLn() {
PrintLn(stdout);
}
-void MaybeObject::PrintLn(FILE* out) {
+void Object::PrintLn(FILE* out) {
Print(out);
PrintF(out, "\n");
}
@@ -174,6 +146,12 @@ void HeapObject::HeapObjectPrint(FILE* out) {
case JS_MAP_TYPE:
JSMap::cast(this)->JSMapPrint(out);
break;
+ case JS_SET_ITERATOR_TYPE:
+ JSSetIterator::cast(this)->JSSetIteratorPrint(out);
+ break;
+ case JS_MAP_ITERATOR_TYPE:
+ JSMapIterator::cast(this)->JSMapIteratorPrint(out);
+ break;
case JS_WEAK_MAP_TYPE:
JSWeakMap::cast(this)->JSWeakMapPrint(out);
break;
@@ -271,7 +249,6 @@ void JSObject::PrintProperties(FILE* out) {
case HANDLER: // only in lookup results, not in descriptors
case INTERCEPTOR: // only in lookup results, not in descriptors
// There are no transitions in the descriptor array.
- case TRANSITION:
case NONEXISTENT:
UNREACHABLE();
break;
@@ -428,7 +405,6 @@ void JSObject::PrintTransitions(FILE* out) {
case NORMAL:
case HANDLER:
case INTERCEPTOR:
- case TRANSITION:
case NONEXISTENT:
UNREACHABLE();
break;
@@ -566,8 +542,6 @@ void TypeFeedbackInfo::TypeFeedbackInfoPrint(FILE* out) {
HeapObject::PrintHeader(out, "TypeFeedbackInfo");
PrintF(out, " - ic_total_count: %d, ic_with_type_info_count: %d\n",
ic_total_count(), ic_with_type_info_count());
- PrintF(out, " - feedback_vector: ");
- feedback_vector()->FixedArrayPrint(out);
}
@@ -724,7 +698,7 @@ void JSProxy::JSProxyPrint(FILE* out) {
PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map()));
PrintF(out, " - handler = ");
handler()->Print(out);
- PrintF(out, " - hash = ");
+ PrintF(out, "\n - hash = ");
hash()->Print(out);
PrintF(out, "\n");
}
@@ -735,9 +709,9 @@ void JSFunctionProxy::JSFunctionProxyPrint(FILE* out) {
PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map()));
PrintF(out, " - handler = ");
handler()->Print(out);
- PrintF(out, " - call_trap = ");
+ PrintF(out, "\n - call_trap = ");
call_trap()->Print(out);
- PrintF(out, " - construct_trap = ");
+ PrintF(out, "\n - construct_trap = ");
construct_trap()->Print(out);
PrintF(out, "\n");
}
@@ -761,6 +735,48 @@ void JSMap::JSMapPrint(FILE* out) {
}
+template<class Derived, class TableType>
+void OrderedHashTableIterator<Derived, TableType>::
+ OrderedHashTableIteratorPrint(FILE* out) {
+ PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map()));
+ PrintF(out, " - table = ");
+ table()->ShortPrint(out);
+ PrintF(out, "\n - index = ");
+ index()->ShortPrint(out);
+ PrintF(out, "\n - count = ");
+ count()->ShortPrint(out);
+ PrintF(out, "\n - kind = ");
+ kind()->ShortPrint(out);
+ PrintF(out, "\n - next_iterator = ");
+ next_iterator()->ShortPrint(out);
+ PrintF(out, "\n - previous_iterator = ");
+ previous_iterator()->ShortPrint(out);
+ PrintF(out, "\n");
+}
+
+
+template void
+OrderedHashTableIterator<JSSetIterator,
+ OrderedHashSet>::OrderedHashTableIteratorPrint(FILE* out);
+
+
+template void
+OrderedHashTableIterator<JSMapIterator,
+ OrderedHashMap>::OrderedHashTableIteratorPrint(FILE* out);
+
+
+void JSSetIterator::JSSetIteratorPrint(FILE* out) {
+ HeapObject::PrintHeader(out, "JSSetIterator");
+ OrderedHashTableIteratorPrint(out);
+}
+
+
+void JSMapIterator::JSMapIteratorPrint(FILE* out) {
+ HeapObject::PrintHeader(out, "JSMapIterator");
+ OrderedHashTableIteratorPrint(out);
+}
+
+
void JSWeakMap::JSWeakMapPrint(FILE* out) {
HeapObject::PrintHeader(out, "JSWeakMap");
PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map()));
@@ -854,6 +870,7 @@ void SharedFunctionInfo::SharedFunctionInfoPrint(FILE* out) {
PrintF(out, " - name: ");
name()->ShortPrint(out);
PrintF(out, "\n - expected_nof_properties: %d", expected_nof_properties());
+ PrintF(out, "\n - ast_node_count: %d", ast_node_count());
PrintF(out, "\n - instance class name = ");
instance_class_name()->Print(out);
PrintF(out, "\n - code = ");
@@ -881,6 +898,8 @@ void SharedFunctionInfo::SharedFunctionInfoPrint(FILE* out) {
PrintF(out, "\n - length = %d", length());
PrintF(out, "\n - optimized_code_map = ");
optimized_code_map()->ShortPrint(out);
+ PrintF(out, "\n - feedback_vector = ");
+ feedback_vector()->FixedArrayPrint(out);
PrintF(out, "\n");
}
@@ -1165,7 +1184,6 @@ void Script::ScriptPrint(FILE* out) {
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
void DebugInfo::DebugInfoPrint(FILE* out) {
HeapObject::PrintHeader(out, "DebugInfo");
PrintF(out, "\n - shared: ");
@@ -1187,7 +1205,6 @@ void BreakPointInfo::BreakPointInfoPrint(FILE* out) {
PrintF(out, "\n - break_point_objects: ");
break_point_objects()->ShortPrint(out);
}
-#endif // ENABLE_DEBUGGER_SUPPORT
void DescriptorArray::PrintDescriptors(FILE* out) {
@@ -1223,7 +1240,6 @@ void TransitionArray::PrintTransitions(FILE* out) {
case NORMAL:
case HANDLER:
case INTERCEPTOR:
- case TRANSITION:
case NONEXISTENT:
UNREACHABLE();
break;
diff --git a/deps/v8/src/objects-visiting-inl.h b/deps/v8/src/objects-visiting-inl.h
index 31117bb945..bb2e99243a 100644
--- a/deps/v8/src/objects-visiting-inl.h
+++ b/deps/v8/src/objects-visiting-inl.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_OBJECTS_VISITING_INL_H_
#define V8_OBJECTS_VISITING_INL_H_
@@ -309,12 +286,14 @@ void StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget(
// Monomorphic ICs are preserved when possible, but need to be flushed
// when they might be keeping a Context alive, or when the heap is about
// to be serialized.
+
if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub()
&& (target->ic_state() == MEGAMORPHIC || target->ic_state() == GENERIC ||
target->ic_state() == POLYMORPHIC || heap->flush_monomorphic_ics() ||
- Serializer::enabled() || target->ic_age() != heap->global_ic_age())) {
- IC::Clear(target->GetIsolate(), rinfo->pc(),
- rinfo->host()->constant_pool());
+ Serializer::enabled(heap->isolate()) ||
+ target->ic_age() != heap->global_ic_age() ||
+ target->is_invalidated_weak_stub())) {
+ IC::Clear(heap->isolate(), rinfo->pc(), rinfo->host()->constant_pool());
target = Code::GetCodeFromTargetAddress(rinfo->target_address());
}
heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
@@ -427,10 +406,7 @@ void StaticMarkingVisitor<StaticVisitor>::VisitCode(
Map* map, HeapObject* object) {
Heap* heap = map->GetHeap();
Code* code = Code::cast(object);
- if (FLAG_cleanup_code_caches_at_gc) {
- code->ClearTypeFeedbackInfo(heap);
- }
- if (FLAG_age_code && !Serializer::enabled()) {
+ if (FLAG_age_code && !Serializer::enabled(heap->isolate())) {
code->MakeOlder(heap->mark_compact_collector()->marking_parity());
}
code->CodeIterateBody<StaticVisitor>(heap);
@@ -445,6 +421,9 @@ void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfo(
if (shared->ic_age() != heap->global_ic_age()) {
shared->ResetForNewContext(heap->global_ic_age());
}
+ if (FLAG_cleanup_code_caches_at_gc) {
+ shared->ClearTypeFeedbackInfo();
+ }
if (FLAG_cache_optimized_code &&
FLAG_flush_optimized_code_cache &&
!shared->optimized_code_map()->IsSmi()) {
@@ -498,8 +477,19 @@ void StaticMarkingVisitor<StaticVisitor>::VisitConstantPoolArray(
}
for (int i = 0; i < constant_pool->count_of_heap_ptr_entries(); i++) {
int index = constant_pool->first_heap_ptr_index() + i;
- StaticVisitor::VisitPointer(heap,
- constant_pool->RawFieldOfElementAt(index));
+ Object** slot = constant_pool->RawFieldOfElementAt(index);
+ HeapObject* object = HeapObject::cast(*slot);
+ heap->mark_compact_collector()->RecordSlot(slot, slot, object);
+ bool is_weak_object =
+ (constant_pool->get_weak_object_state() ==
+ ConstantPoolArray::WEAK_OBJECTS_IN_OPTIMIZED_CODE &&
+ Code::IsWeakObjectInOptimizedCode(object)) ||
+ (constant_pool->get_weak_object_state() ==
+ ConstantPoolArray::WEAK_OBJECTS_IN_IC &&
+ Code::IsWeakObjectInIC(object));
+ if (!is_weak_object) {
+ StaticVisitor::MarkObject(heap, object);
+ }
}
}
@@ -615,12 +605,9 @@ void StaticMarkingVisitor<StaticVisitor>::MarkMapContents(
// array to prevent visiting it later. Skip recording the transition
// array slot, since it will be implicitly recorded when the pointer
// fields of this map are visited.
- TransitionArray* transitions = map->unchecked_transition_array();
- if (transitions->IsTransitionArray()) {
+ if (map->HasTransitionArray()) {
+ TransitionArray* transitions = map->transitions();
MarkTransitionArray(heap, transitions);
- } else {
- // Already marked by marking map->GetBackPointer() above.
- ASSERT(transitions->IsMap() || transitions->IsUndefined());
}
// Since descriptor arrays are potentially shared, ensure that only the
diff --git a/deps/v8/src/objects-visiting.cc b/deps/v8/src/objects-visiting.cc
index 16c51676b5..24cff3487f 100644
--- a/deps/v8/src/objects-visiting.cc
+++ b/deps/v8/src/objects-visiting.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -163,6 +140,8 @@ StaticVisitorBase::VisitorId StaticVisitorBase::GetVisitorId(
case JS_GLOBAL_OBJECT_TYPE:
case JS_BUILTINS_OBJECT_TYPE:
case JS_MESSAGE_OBJECT_TYPE:
+ case JS_SET_ITERATOR_TYPE:
+ case JS_MAP_ITERATOR_TYPE:
return GetVisitorIdForSize(kVisitJSObject,
kVisitJSObjectGeneric,
instance_size);
@@ -211,4 +190,281 @@ StaticVisitorBase::VisitorId StaticVisitorBase::GetVisitorId(
}
}
+
+template <class T>
+struct WeakListVisitor;
+
+
+template <class T>
+Object* VisitWeakList(Heap* heap,
+ Object* list,
+ WeakObjectRetainer* retainer,
+ bool record_slots) {
+ Object* undefined = heap->undefined_value();
+ Object* head = undefined;
+ T* tail = NULL;
+ MarkCompactCollector* collector = heap->mark_compact_collector();
+ while (list != undefined) {
+ // Check whether to keep the candidate in the list.
+ T* candidate = reinterpret_cast<T*>(list);
+ Object* retained = retainer->RetainAs(list);
+ if (retained != NULL) {
+ if (head == undefined) {
+ // First element in the list.
+ head = retained;
+ } else {
+ // Subsequent elements in the list.
+ ASSERT(tail != NULL);
+ WeakListVisitor<T>::SetWeakNext(tail, retained);
+ if (record_slots) {
+ Object** next_slot =
+ HeapObject::RawField(tail, WeakListVisitor<T>::WeakNextOffset());
+ collector->RecordSlot(next_slot, next_slot, retained);
+ }
+ }
+ // Retained object is new tail.
+ ASSERT(!retained->IsUndefined());
+ candidate = reinterpret_cast<T*>(retained);
+ tail = candidate;
+
+
+ // tail is a live object, visit it.
+ WeakListVisitor<T>::VisitLiveObject(
+ heap, tail, retainer, record_slots);
+ } else {
+ WeakListVisitor<T>::VisitPhantomObject(heap, candidate);
+ }
+
+ // Move to next element in the list.
+ list = WeakListVisitor<T>::WeakNext(candidate);
+ }
+
+ // Terminate the list if there is one or more elements.
+ if (tail != NULL) {
+ WeakListVisitor<T>::SetWeakNext(tail, undefined);
+ }
+ return head;
+}
+
+
+template <class T>
+static void ClearWeakList(Heap* heap,
+ Object* list) {
+ Object* undefined = heap->undefined_value();
+ while (list != undefined) {
+ T* candidate = reinterpret_cast<T*>(list);
+ list = WeakListVisitor<T>::WeakNext(candidate);
+ WeakListVisitor<T>::SetWeakNext(candidate, undefined);
+ }
+}
+
+
+template<>
+struct WeakListVisitor<JSFunction> {
+ static void SetWeakNext(JSFunction* function, Object* next) {
+ function->set_next_function_link(next);
+ }
+
+ static Object* WeakNext(JSFunction* function) {
+ return function->next_function_link();
+ }
+
+ static int WeakNextOffset() {
+ return JSFunction::kNextFunctionLinkOffset;
+ }
+
+ static void VisitLiveObject(Heap*, JSFunction*,
+ WeakObjectRetainer*, bool) {
+ }
+
+ static void VisitPhantomObject(Heap*, JSFunction*) {
+ }
+};
+
+
+template<>
+struct WeakListVisitor<Code> {
+ static void SetWeakNext(Code* code, Object* next) {
+ code->set_next_code_link(next);
+ }
+
+ static Object* WeakNext(Code* code) {
+ return code->next_code_link();
+ }
+
+ static int WeakNextOffset() {
+ return Code::kNextCodeLinkOffset;
+ }
+
+ static void VisitLiveObject(Heap*, Code*,
+ WeakObjectRetainer*, bool) {
+ }
+
+ static void VisitPhantomObject(Heap*, Code*) {
+ }
+};
+
+
+template<>
+struct WeakListVisitor<Context> {
+ static void SetWeakNext(Context* context, Object* next) {
+ context->set(Context::NEXT_CONTEXT_LINK,
+ next,
+ UPDATE_WRITE_BARRIER);
+ }
+
+ static Object* WeakNext(Context* context) {
+ return context->get(Context::NEXT_CONTEXT_LINK);
+ }
+
+ static void VisitLiveObject(Heap* heap,
+ Context* context,
+ WeakObjectRetainer* retainer,
+ bool record_slots) {
+ // Process the three weak lists linked off the context.
+ DoWeakList<JSFunction>(heap, context, retainer, record_slots,
+ Context::OPTIMIZED_FUNCTIONS_LIST);
+ DoWeakList<Code>(heap, context, retainer, record_slots,
+ Context::OPTIMIZED_CODE_LIST);
+ DoWeakList<Code>(heap, context, retainer, record_slots,
+ Context::DEOPTIMIZED_CODE_LIST);
+ }
+
+ template<class T>
+ static void DoWeakList(Heap* heap,
+ Context* context,
+ WeakObjectRetainer* retainer,
+ bool record_slots,
+ int index) {
+ // Visit the weak list, removing dead intermediate elements.
+ Object* list_head = VisitWeakList<T>(heap, context->get(index), retainer,
+ record_slots);
+
+ // Update the list head.
+ context->set(index, list_head, UPDATE_WRITE_BARRIER);
+
+ if (record_slots) {
+ // Record the updated slot if necessary.
+ Object** head_slot = HeapObject::RawField(
+ context, FixedArray::SizeFor(index));
+ heap->mark_compact_collector()->RecordSlot(
+ head_slot, head_slot, list_head);
+ }
+ }
+
+ static void VisitPhantomObject(Heap* heap, Context* context) {
+ ClearWeakList<JSFunction>(heap,
+ context->get(Context::OPTIMIZED_FUNCTIONS_LIST));
+ ClearWeakList<Code>(heap, context->get(Context::OPTIMIZED_CODE_LIST));
+ ClearWeakList<Code>(heap, context->get(Context::DEOPTIMIZED_CODE_LIST));
+ }
+
+ static int WeakNextOffset() {
+ return FixedArray::SizeFor(Context::NEXT_CONTEXT_LINK);
+ }
+};
+
+
+template<>
+struct WeakListVisitor<JSArrayBufferView> {
+ static void SetWeakNext(JSArrayBufferView* obj, Object* next) {
+ obj->set_weak_next(next);
+ }
+
+ static Object* WeakNext(JSArrayBufferView* obj) {
+ return obj->weak_next();
+ }
+
+ static void VisitLiveObject(Heap*,
+ JSArrayBufferView* obj,
+ WeakObjectRetainer* retainer,
+ bool record_slots) {}
+
+ static void VisitPhantomObject(Heap*, JSArrayBufferView*) {}
+
+ static int WeakNextOffset() {
+ return JSArrayBufferView::kWeakNextOffset;
+ }
+};
+
+
+template<>
+struct WeakListVisitor<JSArrayBuffer> {
+ static void SetWeakNext(JSArrayBuffer* obj, Object* next) {
+ obj->set_weak_next(next);
+ }
+
+ static Object* WeakNext(JSArrayBuffer* obj) {
+ return obj->weak_next();
+ }
+
+ static void VisitLiveObject(Heap* heap,
+ JSArrayBuffer* array_buffer,
+ WeakObjectRetainer* retainer,
+ bool record_slots) {
+ Object* typed_array_obj =
+ VisitWeakList<JSArrayBufferView>(
+ heap,
+ array_buffer->weak_first_view(),
+ retainer, record_slots);
+ array_buffer->set_weak_first_view(typed_array_obj);
+ if (typed_array_obj != heap->undefined_value() && record_slots) {
+ Object** slot = HeapObject::RawField(
+ array_buffer, JSArrayBuffer::kWeakFirstViewOffset);
+ heap->mark_compact_collector()->RecordSlot(slot, slot, typed_array_obj);
+ }
+ }
+
+ static void VisitPhantomObject(Heap* heap, JSArrayBuffer* phantom) {
+ Runtime::FreeArrayBuffer(heap->isolate(), phantom);
+ }
+
+ static int WeakNextOffset() {
+ return JSArrayBuffer::kWeakNextOffset;
+ }
+};
+
+
+template<>
+struct WeakListVisitor<AllocationSite> {
+ static void SetWeakNext(AllocationSite* obj, Object* next) {
+ obj->set_weak_next(next);
+ }
+
+ static Object* WeakNext(AllocationSite* obj) {
+ return obj->weak_next();
+ }
+
+ static void VisitLiveObject(Heap* heap,
+ AllocationSite* site,
+ WeakObjectRetainer* retainer,
+ bool record_slots) {}
+
+ static void VisitPhantomObject(Heap* heap, AllocationSite* phantom) {}
+
+ static int WeakNextOffset() {
+ return AllocationSite::kWeakNextOffset;
+ }
+};
+
+
+template Object* VisitWeakList<Code>(
+ Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots);
+
+
+template Object* VisitWeakList<JSFunction>(
+ Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots);
+
+
+template Object* VisitWeakList<Context>(
+ Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots);
+
+
+template Object* VisitWeakList<JSArrayBuffer>(
+ Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots);
+
+
+template Object* VisitWeakList<AllocationSite>(
+ Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots);
+
} } // namespace v8::internal
diff --git a/deps/v8/src/objects-visiting.h b/deps/v8/src/objects-visiting.h
index de8ca6d055..05f82574cc 100644
--- a/deps/v8/src/objects-visiting.h
+++ b/deps/v8/src/objects-visiting.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_OBJECTS_VISITING_H_
#define V8_OBJECTS_VISITING_H_
@@ -483,6 +460,20 @@ VisitorDispatchTable<typename StaticMarkingVisitor<StaticVisitor>::Callback>
StaticMarkingVisitor<StaticVisitor>::table_;
+class WeakObjectRetainer;
+
+
+// A weak list is single linked list where each element has a weak pointer to
+// the next element. Given the head of the list, this function removes dead
+// elements from the list and if requested records slots for next-element
+// pointers. The template parameter T is a WeakListVisitor that defines how to
+// access the next-element pointers.
+template <class T>
+Object* VisitWeakList(Heap* heap,
+ Object* list,
+ WeakObjectRetainer* retainer,
+ bool record_slots);
+
} } // namespace v8::internal
#endif // V8_OBJECTS_VISITING_H_
diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc
index 45220ee291..956e46f73b 100644
--- a/deps/v8/src/objects.cc
+++ b/deps/v8/src/objects.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -49,6 +26,7 @@
#include "macro-assembler.h"
#include "mark-compact.h"
#include "safepoint-table.h"
+#include "string-search.h"
#include "string-stream.h"
#include "utils.h"
@@ -60,53 +38,43 @@
namespace v8 {
namespace internal {
-
-MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor,
- Object* value) {
- Object* result;
- { MaybeObject* maybe_result =
- constructor->GetHeap()->AllocateJSObject(constructor);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- JSValue::cast(result)->set_value(value);
- return result;
-}
-
-
-MaybeObject* Object::ToObject(Context* native_context) {
- if (IsNumber()) {
- return CreateJSValue(native_context->number_function(), this);
- } else if (IsBoolean()) {
- return CreateJSValue(native_context->boolean_function(), this);
- } else if (IsString()) {
- return CreateJSValue(native_context->string_function(), this);
- } else if (IsSymbol()) {
- return CreateJSValue(native_context->symbol_function(), this);
+Handle<HeapType> Object::OptimalType(Isolate* isolate,
+ Representation representation) {
+ if (representation.IsNone()) return HeapType::None(isolate);
+ if (FLAG_track_field_types) {
+ if (representation.IsHeapObject() && IsHeapObject()) {
+ // We can track only JavaScript objects with stable maps.
+ Handle<Map> map(HeapObject::cast(this)->map(), isolate);
+ if (map->is_stable() &&
+ map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE &&
+ map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE) {
+ return HeapType::Class(map, isolate);
+ }
+ }
}
- ASSERT(IsJSObject());
- return this;
+ return HeapType::Any(isolate);
}
-MaybeObject* Object::ToObject(Isolate* isolate) {
- if (IsJSReceiver()) {
- return this;
- } else if (IsNumber()) {
- Context* native_context = isolate->context()->native_context();
- return CreateJSValue(native_context->number_function(), this);
- } else if (IsBoolean()) {
- Context* native_context = isolate->context()->native_context();
- return CreateJSValue(native_context->boolean_function(), this);
- } else if (IsString()) {
- Context* native_context = isolate->context()->native_context();
- return CreateJSValue(native_context->string_function(), this);
- } else if (IsSymbol()) {
- Context* native_context = isolate->context()->native_context();
- return CreateJSValue(native_context->symbol_function(), this);
+MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
+ Handle<Object> object,
+ Handle<Context> native_context) {
+ if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
+ Handle<JSFunction> constructor;
+ if (object->IsNumber()) {
+ constructor = handle(native_context->number_function(), isolate);
+ } else if (object->IsBoolean()) {
+ constructor = handle(native_context->boolean_function(), isolate);
+ } else if (object->IsString()) {
+ constructor = handle(native_context->string_function(), isolate);
+ } else if (object->IsSymbol()) {
+ constructor = handle(native_context->symbol_function(), isolate);
+ } else {
+ return MaybeHandle<JSReceiver>();
}
-
- // Throw a type error.
- return Failure::InternalError();
+ Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
+ Handle<JSValue>::cast(result)->set_value(*object);
+ return result;
}
@@ -132,7 +100,8 @@ bool Object::IsCallable() {
}
-void Object::Lookup(Name* name, LookupResult* result) {
+void Object::Lookup(Handle<Name> name, LookupResult* result) {
+ DisallowHeapAllocation no_gc;
Object* holder = NULL;
if (IsJSReceiver()) {
holder = this;
@@ -156,31 +125,20 @@ void Object::Lookup(Name* name, LookupResult* result) {
}
-Handle<Object> Object::GetPropertyWithReceiver(
+MaybeHandle<Object> Object::GetPropertyWithReceiver(
Handle<Object> object,
Handle<Object> receiver,
Handle<Name> name,
PropertyAttributes* attributes) {
LookupResult lookup(name->GetIsolate());
- object->Lookup(*name, &lookup);
- Handle<Object> result =
+ object->Lookup(name, &lookup);
+ MaybeHandle<Object> result =
GetProperty(object, receiver, &lookup, name, attributes);
ASSERT(*attributes <= ABSENT);
return result;
}
-MaybeObject* Object::GetPropertyWithReceiver(Object* receiver,
- Name* name,
- PropertyAttributes* attributes) {
- LookupResult result(name->GetIsolate());
- Lookup(name, &result);
- MaybeObject* value = GetProperty(receiver, &result, name, attributes);
- ASSERT(*attributes <= ABSENT);
- return value;
-}
-
-
bool Object::ToInt32(int32_t* value) {
if (IsSmi()) {
*value = Smi::cast(this)->value();
@@ -249,9 +207,9 @@ static inline To* CheckedCast(void *from) {
}
-static MaybeObject* PerformCompare(const BitmaskCompareDescriptor& descriptor,
- char* ptr,
- Heap* heap) {
+static Handle<Object> PerformCompare(const BitmaskCompareDescriptor& descriptor,
+ char* ptr,
+ Isolate* isolate) {
uint32_t bitmask = descriptor.bitmask;
uint32_t compare_value = descriptor.compare_value;
uint32_t value;
@@ -271,26 +229,27 @@ static MaybeObject* PerformCompare(const BitmaskCompareDescriptor& descriptor,
break;
default:
UNREACHABLE();
- return NULL;
+ return isolate->factory()->undefined_value();
}
- return heap->ToBoolean((bitmask & value) == (bitmask & compare_value));
+ return isolate->factory()->ToBoolean(
+ (bitmask & value) == (bitmask & compare_value));
}
-static MaybeObject* PerformCompare(const PointerCompareDescriptor& descriptor,
- char* ptr,
- Heap* heap) {
+static Handle<Object> PerformCompare(const PointerCompareDescriptor& descriptor,
+ char* ptr,
+ Isolate* isolate) {
uintptr_t compare_value =
reinterpret_cast<uintptr_t>(descriptor.compare_value);
uintptr_t value = *CheckedCast<uintptr_t>(ptr);
- return heap->ToBoolean(compare_value == value);
+ return isolate->factory()->ToBoolean(compare_value == value);
}
-static MaybeObject* GetPrimitiveValue(
+static Handle<Object> GetPrimitiveValue(
const PrimitiveValueDescriptor& descriptor,
char* ptr,
- Heap* heap) {
+ Isolate* isolate) {
int32_t int32_value = 0;
switch (descriptor.data_type) {
case kDescriptorInt8Type:
@@ -310,29 +269,36 @@ static MaybeObject* GetPrimitiveValue(
break;
case kDescriptorUint32Type: {
uint32_t value = *CheckedCast<uint32_t>(ptr);
- return heap->NumberFromUint32(value);
+ AllowHeapAllocation allow_gc;
+ return isolate->factory()->NewNumberFromUint(value);
}
case kDescriptorBoolType: {
uint8_t byte = *CheckedCast<uint8_t>(ptr);
- return heap->ToBoolean(byte & (0x1 << descriptor.bool_offset));
+ return isolate->factory()->ToBoolean(
+ byte & (0x1 << descriptor.bool_offset));
}
case kDescriptorFloatType: {
float value = *CheckedCast<float>(ptr);
- return heap->NumberFromDouble(value);
+ AllowHeapAllocation allow_gc;
+ return isolate->factory()->NewNumber(value);
}
case kDescriptorDoubleType: {
double value = *CheckedCast<double>(ptr);
- return heap->NumberFromDouble(value);
+ AllowHeapAllocation allow_gc;
+ return isolate->factory()->NewNumber(value);
}
}
- return heap->NumberFromInt32(int32_value);
+ AllowHeapAllocation allow_gc;
+ return isolate->factory()->NewNumberFromInt(int32_value);
}
-static MaybeObject* GetDeclaredAccessorProperty(Object* receiver,
- DeclaredAccessorInfo* info,
- Isolate* isolate) {
- char* current = reinterpret_cast<char*>(receiver);
+static Handle<Object> GetDeclaredAccessorProperty(
+ Handle<Object> receiver,
+ Handle<DeclaredAccessorInfo> info,
+ Isolate* isolate) {
+ DisallowHeapAllocation no_gc;
+ char* current = reinterpret_cast<char*>(*receiver);
DeclaredAccessorDescriptorIterator iterator(info->descriptor());
while (true) {
const DeclaredAccessorDescriptorData* data = iterator.Next();
@@ -340,7 +306,7 @@ static MaybeObject* GetDeclaredAccessorProperty(Object* receiver,
case kDescriptorReturnObject: {
ASSERT(iterator.Complete());
current = *CheckedCast<char*>(current);
- return *CheckedCast<Object*>(current);
+ return handle(*CheckedCast<Object*>(current), isolate);
}
case kDescriptorPointerDereference:
ASSERT(!iterator.Complete());
@@ -363,49 +329,44 @@ static MaybeObject* GetDeclaredAccessorProperty(Object* receiver,
ASSERT(iterator.Complete());
return PerformCompare(data->bitmask_compare_descriptor,
current,
- isolate->heap());
+ isolate);
case kDescriptorPointerCompare:
ASSERT(iterator.Complete());
return PerformCompare(data->pointer_compare_descriptor,
current,
- isolate->heap());
+ isolate);
case kDescriptorPrimitiveValue:
ASSERT(iterator.Complete());
return GetPrimitiveValue(data->primitive_value_descriptor,
current,
- isolate->heap());
+ isolate);
}
}
UNREACHABLE();
- return NULL;
+ return isolate->factory()->undefined_value();
}
Handle<FixedArray> JSObject::EnsureWritableFastElements(
Handle<JSObject> object) {
- CALL_HEAP_FUNCTION(object->GetIsolate(),
- object->EnsureWritableFastElements(),
- FixedArray);
+ ASSERT(object->HasFastSmiOrObjectElements());
+ Isolate* isolate = object->GetIsolate();
+ Handle<FixedArray> elems(FixedArray::cast(object->elements()), isolate);
+ if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
+ Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap(
+ elems, isolate->factory()->fixed_array_map());
+ object->set_elements(*writable_elems);
+ isolate->counters()->cow_arrays_converted()->Increment();
+ return writable_elems;
}
-Handle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
- Handle<Object> receiver,
- Handle<Object> structure,
- Handle<Name> name) {
+MaybeHandle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
+ Handle<Object> receiver,
+ Handle<Object> structure,
+ Handle<Name> name) {
Isolate* isolate = name->GetIsolate();
- // To accommodate both the old and the new api we switch on the
- // data structure used to store the callbacks. Eventually foreign
- // callbacks should be phased out.
- if (structure->IsForeign()) {
- AccessorDescriptor* callback =
- reinterpret_cast<AccessorDescriptor*>(
- Handle<Foreign>::cast(structure)->foreign_address());
- CALL_HEAP_FUNCTION(isolate,
- (callback->getter)(isolate, *receiver, callback->data),
- Object);
- }
-
+ ASSERT(!structure->IsForeign());
// api style callbacks.
if (structure->IsAccessorInfo()) {
Handle<AccessorInfo> accessor_info = Handle<AccessorInfo>::cast(structure);
@@ -415,19 +376,16 @@ Handle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
isolate->factory()->NewTypeError("incompatible_method_receiver",
HandleVector(args,
ARRAY_SIZE(args)));
- isolate->Throw(*error);
- return Handle<Object>::null();
+ return isolate->Throw<Object>(error);
}
// TODO(rossberg): Handling symbols in the API requires changing the API,
// so we do not support it for now.
if (name->IsSymbol()) return isolate->factory()->undefined_value();
if (structure->IsDeclaredAccessorInfo()) {
- CALL_HEAP_FUNCTION(
- isolate,
- GetDeclaredAccessorProperty(*receiver,
- DeclaredAccessorInfo::cast(*structure),
- isolate),
- Object);
+ return GetDeclaredAccessorProperty(
+ receiver,
+ Handle<DeclaredAccessorInfo>::cast(structure),
+ isolate);
}
Handle<ExecutableAccessorInfo> data =
@@ -436,20 +394,19 @@ Handle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
v8::ToCData<v8::AccessorGetterCallback>(data->getter());
if (call_fun == NULL) return isolate->factory()->undefined_value();
- HandleScope scope(isolate);
- Handle<JSObject> self = Handle<JSObject>::cast(receiver);
Handle<String> key = Handle<String>::cast(name);
- LOG(isolate, ApiNamedPropertyAccess("load", *self, *name));
- PropertyCallbackArguments args(isolate, data->data(), *self, *object);
+ LOG(isolate, ApiNamedPropertyAccess("load", *object, *name));
+ PropertyCallbackArguments args(isolate, data->data(), *receiver, *object);
v8::Handle<v8::Value> result =
args.Call(call_fun, v8::Utils::ToLocal(key));
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (result.IsEmpty()) {
return isolate->factory()->undefined_value();
}
Handle<Object> return_value = v8::Utils::OpenHandle(*result);
return_value->VerifyApiCallResultType();
- return scope.CloseAndEscape(return_value);
+ // Rebox handle before return.
+ return handle(*return_value, isolate);
}
// __defineGetter__ callback
@@ -457,102 +414,47 @@ Handle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
isolate);
if (getter->IsSpecFunction()) {
// TODO(rossberg): nicer would be to cast to some JSCallable here...
- CALL_HEAP_FUNCTION(
- isolate,
- object->GetPropertyWithDefinedGetter(*receiver,
- JSReceiver::cast(*getter)),
- Object);
+ return Object::GetPropertyWithDefinedGetter(
+ object, receiver, Handle<JSReceiver>::cast(getter));
}
// Getter is not a function.
return isolate->factory()->undefined_value();
}
-MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw,
- Name* name_raw) {
- Isolate* isolate = GetIsolate();
- HandleScope scope(isolate);
- Handle<Object> receiver(receiver_raw, isolate);
- Handle<Object> name(name_raw, isolate);
+MaybeHandle<Object> JSProxy::GetPropertyWithHandler(Handle<JSProxy> proxy,
+ Handle<Object> receiver,
+ Handle<Name> name) {
+ Isolate* isolate = proxy->GetIsolate();
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
- if (name->IsSymbol()) return isolate->heap()->undefined_value();
+ if (name->IsSymbol()) return isolate->factory()->undefined_value();
Handle<Object> args[] = { receiver, name };
- Handle<Object> result = CallTrap(
- "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args);
- if (isolate->has_pending_exception()) return Failure::Exception();
-
- return *result;
-}
-
-
-Handle<Object> Object::GetProperty(Handle<Object> object,
- Handle<Name> name) {
- // TODO(rossberg): The index test should not be here but in the GetProperty
- // method (or somewhere else entirely). Needs more global clean-up.
- uint32_t index;
- Isolate* isolate = name->GetIsolate();
- if (name->AsArrayIndex(&index)) return GetElement(isolate, object, index);
- CALL_HEAP_FUNCTION(isolate, object->GetProperty(*name), Object);
-}
-
-
-MaybeObject* JSProxy::GetElementWithHandler(Object* receiver,
- uint32_t index) {
- String* name;
- MaybeObject* maybe = GetHeap()->Uint32ToString(index);
- if (!maybe->To<String>(&name)) return maybe;
- return GetPropertyWithHandler(receiver, name);
+ return CallTrap(
+ proxy, "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args);
}
-Handle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy,
- Handle<JSReceiver> receiver,
- uint32_t index,
- Handle<Object> value,
- StrictMode strict_mode) {
- Isolate* isolate = proxy->GetIsolate();
- Handle<String> name = isolate->factory()->Uint32ToString(index);
- return SetPropertyWithHandler(
- proxy, receiver, name, value, NONE, strict_mode);
-}
-
-
-bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) {
- Isolate* isolate = proxy->GetIsolate();
- Handle<String> name = isolate->factory()->Uint32ToString(index);
- return HasPropertyWithHandler(proxy, name);
-}
-
-
-MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver,
- JSReceiver* getter) {
+MaybeHandle<Object> Object::GetPropertyWithDefinedGetter(
+ Handle<Object> object,
+ Handle<Object> receiver,
+ Handle<JSReceiver> getter) {
Isolate* isolate = getter->GetIsolate();
- HandleScope scope(isolate);
- Handle<JSReceiver> fun(getter);
- Handle<Object> self(receiver, isolate);
-#ifdef ENABLE_DEBUGGER_SUPPORT
Debug* debug = isolate->debug();
// Handle stepping into a getter if step into is active.
// TODO(rossberg): should this apply to getters that are function proxies?
- if (debug->StepInActive() && fun->IsJSFunction()) {
+ if (debug->StepInActive() && getter->IsJSFunction()) {
debug->HandleStepIn(
- Handle<JSFunction>::cast(fun), Handle<Object>::null(), 0, false);
+ Handle<JSFunction>::cast(getter), Handle<Object>::null(), 0, false);
}
-#endif
- bool has_pending_exception;
- Handle<Object> result = Execution::Call(
- isolate, fun, self, 0, NULL, &has_pending_exception, true);
- // Check for pending exception and return the result.
- if (has_pending_exception) return Failure::Exception();
- return *result;
+ return Execution::Call(isolate, getter, receiver, 0, NULL, true);
}
// Only deal with CALLBACKS and INTERCEPTOR
-Handle<Object> JSObject::GetPropertyWithFailedAccessCheck(
+MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
Handle<JSObject> object,
Handle<Object> receiver,
LookupResult* result,
@@ -582,7 +484,7 @@ Handle<Object> JSObject::GetPropertyWithFailedAccessCheck(
case CONSTANT: {
// Search ALL_CAN_READ accessors in prototype chain.
LookupResult r(isolate);
- result->holder()->LookupRealNamedPropertyInPrototypes(*name, &r);
+ result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
if (r.IsProperty()) {
return GetPropertyWithFailedAccessCheck(
object, receiver, &r, name, attributes);
@@ -593,7 +495,7 @@ Handle<Object> JSObject::GetPropertyWithFailedAccessCheck(
// If the object has an interceptor, try real named properties.
// No access check in GetPropertyAttributeWithInterceptor.
LookupResult r(isolate);
- result->holder()->LookupRealNamedProperty(*name, &r);
+ result->holder()->LookupRealNamedProperty(name, &r);
if (r.IsProperty()) {
return GetPropertyWithFailedAccessCheck(
object, receiver, &r, name, attributes);
@@ -607,8 +509,8 @@ Handle<Object> JSObject::GetPropertyWithFailedAccessCheck(
// No accessible property found.
*attributes = ABSENT;
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_GET);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_GET);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
}
@@ -643,7 +545,7 @@ PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
if (!continue_search) break;
// Search ALL_CAN_READ accessors in prototype chain.
LookupResult r(object->GetIsolate());
- result->holder()->LookupRealNamedPropertyInPrototypes(*name, &r);
+ result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
if (r.IsProperty()) {
return GetPropertyAttributeWithFailedAccessCheck(
object, &r, name, continue_search);
@@ -656,9 +558,9 @@ PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
// No access check in GetPropertyAttributeWithInterceptor.
LookupResult r(object->GetIsolate());
if (continue_search) {
- result->holder()->LookupRealNamedProperty(*name, &r);
+ result->holder()->LookupRealNamedProperty(name, &r);
} else {
- result->holder()->LocalLookupRealNamedProperty(*name, &r);
+ result->holder()->LocalLookupRealNamedProperty(name, &r);
}
if (!r.IsFound()) break;
return GetPropertyAttributeWithFailedAccessCheck(
@@ -666,13 +568,13 @@ PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
}
case HANDLER:
- case TRANSITION:
case NONEXISTENT:
UNREACHABLE();
}
}
- object->GetIsolate()->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
+ object->GetIsolate()->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
+ // TODO(yangguo): Issue 3269, check for scheduled exception missing?
return ABSENT;
}
@@ -688,6 +590,20 @@ Object* JSObject::GetNormalizedProperty(const LookupResult* result) {
}
+Handle<Object> JSObject::GetNormalizedProperty(Handle<JSObject> object,
+ const LookupResult* result) {
+ ASSERT(!object->HasFastProperties());
+ Isolate* isolate = object->GetIsolate();
+ Handle<Object> value(object->property_dictionary()->ValueAt(
+ result->GetDictionaryEntry()), isolate);
+ if (object->IsGlobalObject()) {
+ value = Handle<Object>(Handle<PropertyCell>::cast(value)->value(), isolate);
+ }
+ ASSERT(!value->IsPropertyCell() && !value->IsCell());
+ return value;
+}
+
+
void JSObject::SetNormalizedProperty(Handle<JSObject> object,
const LookupResult* result,
Handle<Object> value) {
@@ -703,17 +619,6 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object,
}
-// TODO(mstarzinger): Temporary wrapper until handlified.
-static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict,
- Handle<Name> name,
- Handle<Object> value,
- PropertyDetails details) {
- CALL_HEAP_FUNCTION(dict->GetIsolate(),
- dict->Add(*name, *value, details),
- NameDictionary);
-}
-
-
void JSObject::SetNormalizedProperty(Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
@@ -726,15 +631,15 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object,
Handle<String>::cast(name));
}
- int entry = property_dictionary->FindEntry(*name);
+ int entry = property_dictionary->FindEntry(name);
if (entry == NameDictionary::kNotFound) {
Handle<Object> store_value = value;
if (object->IsGlobalObject()) {
store_value = object->GetIsolate()->factory()->NewPropertyCell(value);
}
- property_dictionary =
- NameDictionaryAdd(property_dictionary, name, store_value, details);
+ property_dictionary = NameDictionary::Add(
+ property_dictionary, name, store_value, details);
object->set_properties(*property_dictionary);
return;
}
@@ -760,25 +665,18 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object,
// Please note we have to update the property details.
property_dictionary->DetailsAtPut(entry, details);
} else {
- property_dictionary->SetEntry(entry, *name, *value, details);
+ property_dictionary->SetEntry(entry, name, value, details);
}
}
-// TODO(mstarzinger): Temporary wrapper until target is handlified.
-Handle<NameDictionary> NameDictionaryShrink(Handle<NameDictionary> dict,
- Handle<Name> name) {
- CALL_HEAP_FUNCTION(dict->GetIsolate(), dict->Shrink(*name), NameDictionary);
-}
-
-
Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object,
Handle<Name> name,
DeleteMode mode) {
ASSERT(!object->HasFastProperties());
Isolate* isolate = object->GetIsolate();
Handle<NameDictionary> dictionary(object->property_dictionary());
- int entry = dictionary->FindEntry(*name);
+ int entry = dictionary->FindEntry(name);
if (entry != NameDictionary::kNotFound) {
// If we have a global object set the cell to the hole.
if (object->IsGlobalObject()) {
@@ -798,10 +696,11 @@ Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object,
PropertyCell::SetValueInferType(cell, value);
dictionary->DetailsAtPut(entry, details.AsDeleted());
} else {
- Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate);
+ Handle<Object> deleted(
+ NameDictionary::DeleteProperty(dictionary, entry, mode));
if (*deleted == isolate->heap()->true_value()) {
Handle<NameDictionary> new_properties =
- NameDictionaryShrink(dictionary, name);
+ NameDictionary::Shrink(dictionary, name);
object->set_properties(*new_properties);
}
return deleted;
@@ -826,44 +725,13 @@ bool JSObject::IsDirty() {
}
-Handle<Object> Object::GetProperty(Handle<Object> object,
- Handle<Object> receiver,
- LookupResult* result,
- Handle<Name> key,
- PropertyAttributes* attributes) {
- Isolate* isolate = result->isolate();
- CALL_HEAP_FUNCTION(
- isolate,
- object->GetProperty(*receiver, result, *key, attributes),
- Object);
-}
-
-
-MaybeObject* Object::GetPropertyOrFail(Handle<Object> object,
- Handle<Object> receiver,
- LookupResult* result,
- Handle<Name> key,
- PropertyAttributes* attributes) {
- Isolate* isolate = result->isolate();
- CALL_HEAP_FUNCTION_PASS_EXCEPTION(
- isolate,
- object->GetProperty(*receiver, result, *key, attributes));
-}
-
-
-// TODO(yangguo): handlify this and get rid of.
-MaybeObject* Object::GetProperty(Object* receiver,
- LookupResult* result,
- Name* name,
- PropertyAttributes* attributes) {
+MaybeHandle<Object> Object::GetProperty(Handle<Object> object,
+ Handle<Object> receiver,
+ LookupResult* result,
+ Handle<Name> name,
+ PropertyAttributes* attributes) {
Isolate* isolate = name->GetIsolate();
- Heap* heap = isolate->heap();
-
-#ifdef DEBUG
- // TODO(mstarzinger): Only because of the AssertNoContextChange, drop as soon
- // as this method has been fully handlified.
- HandleScope scope(isolate);
-#endif
+ Factory* factory = isolate->factory();
// Make sure that the top context does not change when doing
// callbacks or interceptor calls.
@@ -877,95 +745,77 @@ MaybeObject* Object::GetProperty(Object* receiver,
// holder in the prototype chain.
// Proxy handlers do not use the proxy's prototype, so we can skip this.
if (!result->IsHandler()) {
- Object* last = result->IsProperty()
- ? result->holder()
- : Object::cast(heap->null_value());
- ASSERT(this != this->GetPrototype(isolate));
- for (Object* current = this;
+ ASSERT(*object != object->GetPrototype(isolate));
+ Handle<Object> last = result->IsProperty()
+ ? Handle<Object>(result->holder(), isolate)
+ : Handle<Object>::cast(factory->null_value());
+ for (Handle<Object> current = object;
true;
- current = current->GetPrototype(isolate)) {
+ current = Handle<Object>(current->GetPrototype(isolate), isolate)) {
if (current->IsAccessCheckNeeded()) {
// Check if we're allowed to read from the current object. Note
// that even though we may not actually end up loading the named
// property from the current object, we still check that we have
// access to it.
- JSObject* checked = JSObject::cast(current);
+ Handle<JSObject> checked = Handle<JSObject>::cast(current);
if (!isolate->MayNamedAccess(checked, name, v8::ACCESS_GET)) {
- HandleScope scope(isolate);
- Handle<Object> value = JSObject::GetPropertyWithFailedAccessCheck(
- handle(checked, isolate),
- handle(receiver, isolate),
- result,
- handle(name, isolate),
- attributes);
- RETURN_IF_EMPTY_HANDLE(isolate, value);
- return *value;
+ return JSObject::GetPropertyWithFailedAccessCheck(
+ checked, receiver, result, name, attributes);
}
}
// Stop traversing the chain once we reach the last object in the
// chain; either the holder of the result or null in case of an
// absent property.
- if (current == last) break;
+ if (current.is_identical_to(last)) break;
}
}
if (!result->IsProperty()) {
*attributes = ABSENT;
- return heap->undefined_value();
+ return factory->undefined_value();
}
*attributes = result->GetAttributes();
- Object* value;
+
+ Handle<Object> value;
switch (result->type()) {
- case NORMAL:
- value = result->holder()->GetNormalizedProperty(result);
- ASSERT(!value->IsTheHole() || result->IsReadOnly());
- return value->IsTheHole() ? heap->undefined_value() : value;
- case FIELD: {
- MaybeObject* maybe_result = result->holder()->FastPropertyAt(
- result->representation(),
- result->GetFieldIndex().field_index());
- if (!maybe_result->To(&value)) return maybe_result;
- ASSERT(!value->IsTheHole() || result->IsReadOnly());
- return value->IsTheHole() ? heap->undefined_value() : value;
+ case NORMAL: {
+ value = JSObject::GetNormalizedProperty(
+ handle(result->holder(), isolate), result);
+ break;
}
+ case FIELD:
+ value = JSObject::FastPropertyAt(handle(result->holder(), isolate),
+ result->representation(),
+ result->GetFieldIndex().field_index());
+ break;
case CONSTANT:
- return result->GetConstant();
- case CALLBACKS: {
- HandleScope scope(isolate);
- Handle<Object> value = JSObject::GetPropertyWithCallback(
+ return handle(result->GetConstant(), isolate);
+ case CALLBACKS:
+ return JSObject::GetPropertyWithCallback(
handle(result->holder(), isolate),
- handle(receiver, isolate),
+ receiver,
handle(result->GetCallbackObject(), isolate),
- handle(name, isolate));
- RETURN_IF_EMPTY_HANDLE(isolate, value);
- return *value;
- }
+ name);
case HANDLER:
- return result->proxy()->GetPropertyWithHandler(receiver, name);
- case INTERCEPTOR: {
- HandleScope scope(isolate);
- Handle<Object> value = JSObject::GetPropertyWithInterceptor(
- handle(result->holder(), isolate),
- handle(receiver, isolate),
- handle(name, isolate),
- attributes);
- RETURN_IF_EMPTY_HANDLE(isolate, value);
- return *value;
- }
- case TRANSITION:
+ return JSProxy::GetPropertyWithHandler(
+ handle(result->proxy(), isolate), receiver, name);
+ case INTERCEPTOR:
+ return JSObject::GetPropertyWithInterceptor(
+ handle(result->holder(), isolate), receiver, name, attributes);
case NONEXISTENT:
UNREACHABLE();
break;
}
- UNREACHABLE();
- return NULL;
+ ASSERT(!value->IsTheHole() || result->IsReadOnly());
+ return value->IsTheHole() ? Handle<Object>::cast(factory->undefined_value())
+ : value;
}
-Handle<Object> Object::GetElementWithReceiver(Isolate* isolate,
- Handle<Object> object,
- Handle<Object> receiver,
- uint32_t index) {
+MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate,
+ Handle<Object> object,
+ Handle<Object> receiver,
+ uint32_t index) {
Handle<Object> holder;
// Iterate up the prototype chain until an element is found or the null
@@ -988,10 +838,8 @@ Handle<Object> Object::GetElementWithReceiver(Isolate* isolate,
holder = Handle<Object>(
native_context->boolean_function()->instance_prototype(), isolate);
} else if (holder->IsJSProxy()) {
- CALL_HEAP_FUNCTION(isolate,
- Handle<JSProxy>::cast(holder)->GetElementWithHandler(
- *receiver, index),
- Object);
+ return JSProxy::GetElementWithHandler(
+ Handle<JSProxy>::cast(holder), receiver, index);
} else {
// Undefined and null have no indexed properties.
ASSERT(holder->IsUndefined() || holder->IsNull());
@@ -1006,9 +854,9 @@ Handle<Object> Object::GetElementWithReceiver(Isolate* isolate,
// Check access rights if needed.
if (js_object->IsAccessCheckNeeded()) {
- if (!isolate->MayIndexedAccessWrapper(js_object, index, v8::ACCESS_GET)) {
- isolate->ReportFailedAccessCheckWrapper(js_object, v8::ACCESS_GET);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) {
+ isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
}
}
@@ -1018,9 +866,11 @@ Handle<Object> Object::GetElementWithReceiver(Isolate* isolate,
}
if (js_object->elements() != isolate->heap()->empty_fixed_array()) {
- Handle<Object> result = js_object->GetElementsAccessor()->Get(
- receiver, js_object, index);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>());
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ js_object->GetElementsAccessor()->Get(receiver, js_object, index),
+ Object);
if (!result->IsTheHole()) return result;
}
}
@@ -1030,6 +880,7 @@ Handle<Object> Object::GetElementWithReceiver(Isolate* isolate,
Object* Object::GetPrototype(Isolate* isolate) {
+ DisallowHeapAllocation no_alloc;
if (IsSmi()) {
Context* context = isolate->context()->native_context();
return context->number_function()->instance_prototype();
@@ -1061,6 +912,12 @@ Object* Object::GetPrototype(Isolate* isolate) {
}
+Handle<Object> Object::GetPrototype(Isolate* isolate,
+ Handle<Object> object) {
+ return handle(object->GetPrototype(isolate), isolate);
+}
+
+
Map* Object::GetMarkerMap(Isolate* isolate) {
if (IsSmi()) return isolate->heap()->heap_number_map();
return HeapObject::cast(this)->map();
@@ -1131,8 +988,6 @@ void Object::ShortPrint(FILE* out) {
void Object::ShortPrint(StringStream* accumulator) {
if (IsSmi()) {
Smi::cast(this)->SmiPrint(accumulator);
- } else if (IsFailure()) {
- Failure::cast(this)->FailurePrint(accumulator);
} else {
HeapObject::cast(this)->HeapObjectShortPrint(accumulator);
}
@@ -1149,16 +1004,6 @@ void Smi::SmiPrint(StringStream* accumulator) {
}
-void Failure::FailurePrint(StringStream* accumulator) {
- accumulator->Add("Failure(%p)", reinterpret_cast<void*>(value()));
-}
-
-
-void Failure::FailurePrint(FILE* out) {
- PrintF(out, "Failure(%p)", reinterpret_cast<void*>(value()));
-}
-
-
// Should a word be prefixed by 'a' or 'an' in order to read naturally in
// English? Returns false for non-ASCII or words that don't start with
// a capital letter. The a/an rule follows pronunciation in English.
@@ -1183,70 +1028,36 @@ static bool AnWord(String* str) {
}
-MaybeObject* String::SlowTryFlatten(PretenureFlag pretenure) {
-#ifdef DEBUG
- // Do not attempt to flatten in debug mode when allocation is not
- // allowed. This is to avoid an assertion failure when allocating.
- // Flattening strings is the only case where we always allow
- // allocation because no GC is performed if the allocation fails.
- if (!AllowHeapAllocation::IsAllowed()) return this;
-#endif
-
- Heap* heap = GetHeap();
- switch (StringShape(this).representation_tag()) {
- case kConsStringTag: {
- ConsString* cs = ConsString::cast(this);
- if (cs->second()->length() == 0) {
- return cs->first();
- }
- // There's little point in putting the flat string in new space if the
- // cons string is in old space. It can never get GCed until there is
- // an old space GC.
- PretenureFlag tenure = heap->InNewSpace(this) ? pretenure : TENURED;
- int len = length();
- Object* object;
- String* result;
- if (IsOneByteRepresentation()) {
- { MaybeObject* maybe_object =
- heap->AllocateRawOneByteString(len, tenure);
- if (!maybe_object->ToObject(&object)) return maybe_object;
- }
- result = String::cast(object);
- String* first = cs->first();
- int first_length = first->length();
- uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
- WriteToFlat(first, dest, 0, first_length);
- String* second = cs->second();
- WriteToFlat(second,
- dest + first_length,
- 0,
- len - first_length);
- } else {
- { MaybeObject* maybe_object =
- heap->AllocateRawTwoByteString(len, tenure);
- if (!maybe_object->ToObject(&object)) return maybe_object;
- }
- result = String::cast(object);
- uc16* dest = SeqTwoByteString::cast(result)->GetChars();
- String* first = cs->first();
- int first_length = first->length();
- WriteToFlat(first, dest, 0, first_length);
- String* second = cs->second();
- WriteToFlat(second,
- dest + first_length,
- 0,
- len - first_length);
- }
- cs->set_first(result);
- cs->set_second(heap->empty_string(), SKIP_WRITE_BARRIER);
- return result;
- }
- default:
- return this;
+Handle<String> String::SlowFlatten(Handle<ConsString> cons,
+ PretenureFlag pretenure) {
+ ASSERT(AllowHeapAllocation::IsAllowed());
+ ASSERT(cons->second()->length() != 0);
+ Isolate* isolate = cons->GetIsolate();
+ int length = cons->length();
+ PretenureFlag tenure = isolate->heap()->InNewSpace(*cons) ? pretenure
+ : TENURED;
+ Handle<SeqString> result;
+ if (cons->IsOneByteRepresentation()) {
+ Handle<SeqOneByteString> flat = isolate->factory()->NewRawOneByteString(
+ length, tenure).ToHandleChecked();
+ DisallowHeapAllocation no_gc;
+ WriteToFlat(*cons, flat->GetChars(), 0, length);
+ result = flat;
+ } else {
+ Handle<SeqTwoByteString> flat = isolate->factory()->NewRawTwoByteString(
+ length, tenure).ToHandleChecked();
+ DisallowHeapAllocation no_gc;
+ WriteToFlat(*cons, flat->GetChars(), 0, length);
+ result = flat;
}
+ cons->set_first(*result);
+ cons->set_second(isolate->heap()->empty_string());
+ ASSERT(result->IsFlat());
+ return result;
}
+
bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
// Externalizing twice leaks the external resource, so it's
// prohibited by the API.
@@ -1280,34 +1091,39 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
// In either case we resort to a short external string instead, omitting
// the field caching the address of the backing store. When we encounter
// short external strings in generated code, we need to bailout to runtime.
+ Map* new_map;
if (size < ExternalString::kSize ||
heap->old_pointer_space()->Contains(this)) {
- this->set_map_no_write_barrier(
- is_internalized
- ? (is_ascii
- ? heap->
- short_external_internalized_string_with_one_byte_data_map()
- : heap->short_external_internalized_string_map())
- : (is_ascii
- ? heap->short_external_string_with_one_byte_data_map()
- : heap->short_external_string_map()));
+ new_map = is_internalized
+ ? (is_ascii
+ ? heap->
+ short_external_internalized_string_with_one_byte_data_map()
+ : heap->short_external_internalized_string_map())
+ : (is_ascii
+ ? heap->short_external_string_with_one_byte_data_map()
+ : heap->short_external_string_map());
} else {
- this->set_map_no_write_barrier(
- is_internalized
- ? (is_ascii
- ? heap->external_internalized_string_with_one_byte_data_map()
- : heap->external_internalized_string_map())
- : (is_ascii
- ? heap->external_string_with_one_byte_data_map()
- : heap->external_string_map()));
+ new_map = is_internalized
+ ? (is_ascii
+ ? heap->external_internalized_string_with_one_byte_data_map()
+ : heap->external_internalized_string_map())
+ : (is_ascii
+ ? heap->external_string_with_one_byte_data_map()
+ : heap->external_string_map());
}
+
+ // Byte size of the external String object.
+ int new_size = this->SizeFromMap(new_map);
+ heap->CreateFillerObjectAt(this->address() + new_size, size - new_size);
+
+ // We are storing the new map using release store after creating a filler for
+ // the left-over space to avoid races with the sweeper thread.
+ this->synchronized_set_map(new_map);
+
ExternalTwoByteString* self = ExternalTwoByteString::cast(this);
self->set_resource(resource);
if (is_internalized) self->Hash(); // Force regeneration of the hash value.
- // Fill the remainder of the string with dead wood.
- int new_size = this->Size(); // Byte size of the external String object.
- heap->CreateFillerObjectAt(this->address() + new_size, size - new_size);
heap->AdjustLiveBytes(this->address(), new_size - size, Heap::FROM_MUTATOR);
return true;
}
@@ -1347,23 +1163,30 @@ bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) {
// In either case we resort to a short external string instead, omitting
// the field caching the address of the backing store. When we encounter
// short external strings in generated code, we need to bailout to runtime.
+ Map* new_map;
if (size < ExternalString::kSize ||
heap->old_pointer_space()->Contains(this)) {
- this->set_map_no_write_barrier(
- is_internalized ? heap->short_external_ascii_internalized_string_map()
- : heap->short_external_ascii_string_map());
+ new_map = is_internalized
+ ? heap->short_external_ascii_internalized_string_map()
+ : heap->short_external_ascii_string_map();
} else {
- this->set_map_no_write_barrier(
- is_internalized ? heap->external_ascii_internalized_string_map()
- : heap->external_ascii_string_map());
+ new_map = is_internalized
+ ? heap->external_ascii_internalized_string_map()
+ : heap->external_ascii_string_map();
}
+
+ // Byte size of the external String object.
+ int new_size = this->SizeFromMap(new_map);
+ heap->CreateFillerObjectAt(this->address() + new_size, size - new_size);
+
+ // We are storing the new map using release store after creating a filler for
+ // the left-over space to avoid races with the sweeper thread.
+ this->synchronized_set_map(new_map);
+
ExternalAsciiString* self = ExternalAsciiString::cast(this);
self->set_resource(resource);
if (is_internalized) self->Hash(); // Force regeneration of the hash value.
- // Fill the remainder of the string with dead wood.
- int new_size = this->Size(); // Byte size of the external String object.
- heap->CreateFillerObjectAt(this->address() + new_size, size - new_size);
heap->AdjustLiveBytes(this->address(), new_size - size, Heap::FROM_MUTATOR);
return true;
}
@@ -1560,7 +1383,9 @@ void Map::PrintGeneralization(FILE* file,
int descriptors,
bool constant_to_field,
Representation old_representation,
- Representation new_representation) {
+ Representation new_representation,
+ HeapType* old_field_type,
+ HeapType* new_field_type) {
PrintF(file, "[generalizing ");
constructor_name()->PrintOn(file);
PrintF(file, "] ");
@@ -1570,13 +1395,19 @@ void Map::PrintGeneralization(FILE* file,
} else {
PrintF(file, "{symbol %p}", static_cast<void*>(name));
}
+ PrintF(file, ":");
if (constant_to_field) {
- PrintF(file, ":c->f");
+ PrintF(file, "c");
} else {
- PrintF(file, ":%s->%s",
- old_representation.Mnemonic(),
- new_representation.Mnemonic());
- }
+ PrintF(file, "%s", old_representation.Mnemonic());
+ PrintF(file, "{");
+ old_field_type->TypePrint(file, HeapType::SEMANTIC_DIM);
+ PrintF(file, "}");
+ }
+ PrintF(file, "->%s", new_representation.Mnemonic());
+ PrintF(file, "{");
+ new_field_type->TypePrint(file, HeapType::SEMANTIC_DIM);
+ PrintF(file, "}");
PrintF(file, " (");
if (strlen(reason) > 0) {
PrintF(file, "%s", reason);
@@ -1805,6 +1636,8 @@ void HeapObject::IterateBody(InstanceType type, int object_size,
case JS_DATA_VIEW_TYPE:
case JS_SET_TYPE:
case JS_MAP_TYPE:
+ case JS_SET_ITERATOR_TYPE:
+ case JS_MAP_ITERATOR_TYPE:
case JS_WEAK_MAP_TYPE:
case JS_WEAK_SET_TYPE:
case JS_REGEXP_TYPE:
@@ -1954,28 +1787,38 @@ String* JSReceiver::constructor_name() {
}
-// TODO(mstarzinger): Temporary wrapper until handlified.
-static Handle<Object> NewStorageFor(Isolate* isolate,
- Handle<Object> object,
- Representation representation) {
- Heap* heap = isolate->heap();
- CALL_HEAP_FUNCTION(isolate,
- object->AllocateNewStorageFor(heap, representation),
- Object);
-}
+MaybeHandle<Map> Map::CopyWithField(Handle<Map> map,
+ Handle<Name> name,
+ Handle<HeapType> type,
+ PropertyAttributes attributes,
+ Representation representation,
+ TransitionFlag flag) {
+ ASSERT(DescriptorArray::kNotFound ==
+ map->instance_descriptors()->Search(
+ *name, map->NumberOfOwnDescriptors()));
+ // Ensure the descriptor array does not get too big.
+ if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) {
+ return MaybeHandle<Map>();
+ }
-static MaybeObject* CopyAddFieldDescriptor(Map* map,
- Name* name,
- int index,
- PropertyAttributes attributes,
- Representation representation,
- TransitionFlag flag) {
- Map* new_map;
- FieldDescriptor new_field_desc(name, index, attributes, representation);
- MaybeObject* maybe_map = map->CopyAddDescriptor(&new_field_desc, flag);
- if (!maybe_map->To(&new_map)) return maybe_map;
- int unused_property_fields = map->unused_property_fields() - 1;
+ // Normalize the object if the name is an actual name (not the
+ // hidden strings) and is not a real identifier.
+ // Normalize the object if it will have too many fast properties.
+ Isolate* isolate = map->GetIsolate();
+ if (!name->IsCacheable(isolate)) return MaybeHandle<Map>();
+
+ // Compute the new index for new field.
+ int index = map->NextFreePropertyIndex();
+
+ if (map->instance_type() == JS_CONTEXT_EXTENSION_OBJECT_TYPE) {
+ representation = Representation::Tagged();
+ type = HeapType::Any(isolate);
+ }
+
+ FieldDescriptor new_field_desc(name, index, type, attributes, representation);
+ Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag);
+ int unused_property_fields = new_map->unused_property_fields() - 1;
if (unused_property_fields < 0) {
unused_property_fields += JSObject::kFieldsAdded;
}
@@ -1984,16 +1827,19 @@ static MaybeObject* CopyAddFieldDescriptor(Map* map,
}
-static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map,
- Handle<Name> name,
- int index,
- PropertyAttributes attributes,
- Representation representation,
- TransitionFlag flag) {
- CALL_HEAP_FUNCTION(map->GetIsolate(),
- CopyAddFieldDescriptor(
- *map, *name, index, attributes, representation, flag),
- Map);
+MaybeHandle<Map> Map::CopyWithConstant(Handle<Map> map,
+ Handle<Name> name,
+ Handle<Object> constant,
+ PropertyAttributes attributes,
+ TransitionFlag flag) {
+ // Ensure the descriptor array does not get too big.
+ if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) {
+ return MaybeHandle<Map>();
+ }
+
+ // Allocate new instance descriptors with (name, constant) added.
+ ConstantDescriptor new_constant_desc(name, constant, attributes);
+ return Map::CopyAddDescriptor(map, &new_constant_desc, flag);
}
@@ -2005,84 +1851,27 @@ void JSObject::AddFastProperty(Handle<JSObject> object,
ValueType value_type,
TransitionFlag flag) {
ASSERT(!object->IsJSGlobalProxy());
- ASSERT(DescriptorArray::kNotFound ==
- object->map()->instance_descriptors()->Search(
- *name, object->map()->NumberOfOwnDescriptors()));
- // Normalize the object if the name is an actual name (not the
- // hidden strings) and is not a real identifier.
- // Normalize the object if it will have too many fast properties.
- Isolate* isolate = object->GetIsolate();
- if (!name->IsCacheable(isolate) ||
- object->TooManyFastProperties(store_mode)) {
- NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
- AddSlowProperty(object, name, value, attributes);
- return;
+ MaybeHandle<Map> maybe_map;
+ if (value->IsJSFunction()) {
+ maybe_map = Map::CopyWithConstant(
+ handle(object->map()), name, value, attributes, flag);
+ } else if (!object->TooManyFastProperties(store_mode)) {
+ Isolate* isolate = object->GetIsolate();
+ Representation representation = value->OptimalRepresentation(value_type);
+ maybe_map = Map::CopyWithField(
+ handle(object->map(), isolate), name,
+ value->OptimalType(isolate, representation),
+ attributes, representation, flag);
}
- // Compute the new index for new field.
- int index = object->map()->NextFreePropertyIndex();
-
- // Allocate new instance descriptors with (name, index) added
- if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED;
- Representation representation = value->OptimalRepresentation(value_type);
- Handle<Map> new_map = CopyAddFieldDescriptor(
- handle(object->map()), name, index, attributes, representation, flag);
-
- JSObject::MigrateToMap(object, new_map);
-
- if (representation.IsDouble()) {
- // Nothing more to be done.
- if (value->IsUninitialized()) return;
- HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index));
- box->set_value(value->Number());
- } else {
- object->FastPropertyAtPut(index, *value);
+ Handle<Map> new_map;
+ if (!maybe_map.ToHandle(&new_map)) {
+ NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
+ return;
}
-}
-
-
-static MaybeObject* CopyAddConstantDescriptor(Map* map,
- Name* name,
- Object* value,
- PropertyAttributes attributes,
- TransitionFlag flag) {
- ConstantDescriptor new_constant_desc(name, value, attributes);
- return map->CopyAddDescriptor(&new_constant_desc, flag);
-}
-
-
-static Handle<Map> CopyAddConstantDescriptor(Handle<Map> map,
- Handle<Name> name,
- Handle<Object> value,
- PropertyAttributes attributes,
- TransitionFlag flag) {
- CALL_HEAP_FUNCTION(map->GetIsolate(),
- CopyAddConstantDescriptor(
- *map, *name, *value, attributes, flag),
- Map);
-}
-
-
-void JSObject::AddConstantProperty(Handle<JSObject> object,
- Handle<Name> name,
- Handle<Object> constant,
- PropertyAttributes attributes,
- TransitionFlag initial_flag) {
- TransitionFlag flag =
- // Do not add transitions to global objects.
- (object->IsGlobalObject() ||
- // Don't add transitions to special properties with non-trivial
- // attributes.
- attributes != NONE)
- ? OMIT_TRANSITION
- : initial_flag;
-
- // Allocate new instance descriptors with (name, constant) added.
- Handle<Map> new_map = CopyAddConstantDescriptor(
- handle(object->map()), name, constant, attributes, flag);
- JSObject::MigrateToMap(object, new_map);
+ JSObject::MigrateToNewProperty(object, new_map, value);
}
@@ -2095,7 +1884,7 @@ void JSObject::AddSlowProperty(Handle<JSObject> object,
Handle<NameDictionary> dict(object->property_dictionary());
if (object->IsGlobalObject()) {
// In case name is an orphaned property reuse the cell.
- int entry = dict->FindEntry(*name);
+ int entry = dict->FindEntry(name);
if (entry != NameDictionary::kNotFound) {
Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry)));
PropertyCell::SetValueInferType(cell, value);
@@ -2104,7 +1893,7 @@ void JSObject::AddSlowProperty(Handle<JSObject> object,
int index = dict->NextEnumerationIndex();
PropertyDetails details = PropertyDetails(attributes, NORMAL, index);
dict->SetNextEnumerationIndex(index + 1);
- dict->SetEntry(entry, *name, *cell, details);
+ dict->SetEntry(entry, name, cell, details);
return;
}
Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(value);
@@ -2112,21 +1901,23 @@ void JSObject::AddSlowProperty(Handle<JSObject> object,
value = cell;
}
PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
- Handle<NameDictionary> result = NameDictionaryAdd(dict, name, value, details);
+ Handle<NameDictionary> result =
+ NameDictionary::Add(dict, name, value, details);
if (*dict != *result) object->set_properties(*result);
}
-Handle<Object> JSObject::AddProperty(Handle<JSObject> object,
- Handle<Name> name,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictMode strict_mode,
- JSReceiver::StoreFromKeyed store_mode,
- ExtensibilityCheck extensibility_check,
- ValueType value_type,
- StoreMode mode,
- TransitionFlag transition_flag) {
+MaybeHandle<Object> JSObject::AddProperty(
+ Handle<JSObject> object,
+ Handle<Name> name,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode,
+ JSReceiver::StoreFromKeyed store_mode,
+ ExtensibilityCheck extensibility_check,
+ ValueType value_type,
+ StoreMode mode,
+ TransitionFlag transition_flag) {
ASSERT(!object->IsJSGlobalProxy());
Isolate* isolate = object->GetIsolate();
@@ -2143,31 +1934,16 @@ Handle<Object> JSObject::AddProperty(Handle<JSObject> object,
Handle<Object> args[1] = { name };
Handle<Object> error = isolate->factory()->NewTypeError(
"object_not_extensible", HandleVector(args, ARRAY_SIZE(args)));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
}
if (object->HasFastProperties()) {
- // Ensure the descriptor array does not get too big.
- if (object->map()->NumberOfOwnDescriptors() <= kMaxNumberOfDescriptors) {
- // TODO(verwaest): Support other constants.
- // if (mode == ALLOW_AS_CONSTANT &&
- // !value->IsTheHole() &&
- // !value->IsConsString()) {
- if (value->IsJSFunction()) {
- AddConstantProperty(object, name, value, attributes, transition_flag);
- } else {
- AddFastProperty(object, name, value, attributes, store_mode,
- value_type, transition_flag);
- }
- } else {
- // Normalize the object to prevent very large instance descriptors.
- // This eliminates unwanted N^2 allocation and lookup behavior.
- NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
- AddSlowProperty(object, name, value, attributes);
- }
- } else {
+ AddFastProperty(object, name, value, attributes, store_mode,
+ value_type, transition_flag);
+ }
+
+ if (!object->HasFastProperties()) {
AddSlowProperty(object, name, value, attributes);
}
@@ -2181,38 +1957,50 @@ Handle<Object> JSObject::AddProperty(Handle<JSObject> object,
}
+Context* JSObject::GetCreationContext() {
+ Object* constructor = this->map()->constructor();
+ JSFunction* function;
+ if (!constructor->IsJSFunction()) {
+ // Functions have null as a constructor,
+ // but any JSFunction knows its context immediately.
+ function = JSFunction::cast(this);
+ } else {
+ function = JSFunction::cast(constructor);
+ }
+
+ return function->context()->native_context();
+}
+
+
void JSObject::EnqueueChangeRecord(Handle<JSObject> object,
const char* type_str,
Handle<Name> name,
Handle<Object> old_value) {
+ ASSERT(!object->IsJSGlobalProxy());
+ ASSERT(!object->IsJSGlobalObject());
Isolate* isolate = object->GetIsolate();
HandleScope scope(isolate);
Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str);
- if (object->IsJSGlobalObject()) {
- object = handle(JSGlobalObject::cast(*object)->global_receiver(), isolate);
- }
Handle<Object> args[] = { type, object, name, old_value };
int argc = name.is_null() ? 2 : old_value->IsTheHole() ? 3 : 4;
- bool threw;
Execution::Call(isolate,
Handle<JSFunction>(isolate->observers_notify_change()),
isolate->factory()->undefined_value(),
- argc, args,
- &threw);
- ASSERT(!threw);
+ argc, args).Assert();
}
-Handle<Object> JSObject::SetPropertyPostInterceptor(
+MaybeHandle<Object> JSObject::SetPropertyPostInterceptor(
Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
StrictMode strict_mode) {
// Check local property, ignore interceptor.
- LookupResult result(object->GetIsolate());
- object->LocalLookupRealNamedProperty(*name, &result);
+ Isolate* isolate = object->GetIsolate();
+ LookupResult result(isolate);
+ object->LocalLookupRealNamedProperty(name, &result);
if (!result.IsFound()) {
object->map()->LookupTransition(*object, *name, &result);
}
@@ -2223,8 +2011,12 @@ Handle<Object> JSObject::SetPropertyPostInterceptor(
strict_mode, MAY_BE_STORE_FROM_KEYED);
}
bool done = false;
- Handle<Object> result_object = SetPropertyViaPrototypes(
- object, name, value, attributes, strict_mode, &done);
+ Handle<Object> result_object;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result_object,
+ SetPropertyViaPrototypes(
+ object, name, value, attributes, strict_mode, &done),
+ Object);
if (done) return result_object;
// Add a new real property.
return AddProperty(object, name, value, attributes, strict_mode);
@@ -2236,7 +2028,7 @@ static void ReplaceSlowProperty(Handle<JSObject> object,
Handle<Object> value,
PropertyAttributes attributes) {
NameDictionary* dictionary = object->property_dictionary();
- int old_index = dictionary->FindEntry(*name);
+ int old_index = dictionary->FindEntry(name);
int new_enumeration_index = 0; // 0 means "Use the next available index."
if (old_index != -1) {
// All calls to ReplaceSlowProperty have had all transitions removed.
@@ -2297,7 +2089,9 @@ static void RightTrimFixedArray(Heap* heap, FixedArray* elms, int to_trim) {
// we still do it.
heap->CreateFillerObjectAt(new_end, size_delta);
- elms->set_length(len - to_trim);
+ // We are storing the new length using release store after creating a filler
+ // for the left-over space to avoid races with the sweeper thread.
+ elms->synchronized_set_length(len - to_trim);
heap->AdjustLiveBytes(elms->address(), -size_delta, mode);
@@ -2346,6 +2140,18 @@ bool Map::InstancesNeedRewriting(Map* target,
}
+Handle<TransitionArray> Map::SetElementsTransitionMap(
+ Handle<Map> map, Handle<Map> transitioned_map) {
+ Handle<TransitionArray> transitions = TransitionArray::CopyInsert(
+ map,
+ map->GetIsolate()->factory()->elements_transition_symbol(),
+ transitioned_map,
+ FULL_TRANSITION);
+ map->set_transitions(*transitions);
+ return transitions;
+}
+
+
// To migrate an instance to a map:
// - First check whether the instance needs to be rewritten. If not, simply
// change the map.
@@ -2372,7 +2178,9 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
// converted to doubles.
if (!old_map->InstancesNeedRewriting(
*new_map, number_of_fields, inobject, unused)) {
- object->set_map(*new_map);
+ // Writing the new map here does not require synchronization since it does
+ // not change the actual object size.
+ object->synchronized_set_map(*new_map);
return;
}
@@ -2408,7 +2216,7 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
if (old_details.representation().IsNone()) {
value = handle(Smi::FromInt(0), isolate);
}
- value = NewStorageFor(isolate, value, details.representation());
+ value = Object::NewStorageFor(isolate, value, details.representation());
}
ASSERT(!(details.representation().IsDouble() && value->IsSmi()));
int target_index = new_descriptors->GetFieldIndex(i) - inobject;
@@ -2419,12 +2227,15 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
for (int i = old_nof; i < new_nof; i++) {
PropertyDetails details = new_descriptors->GetDetails(i);
if (details.type() != FIELD) continue;
+ Handle<Object> value;
if (details.representation().IsDouble()) {
- int target_index = new_descriptors->GetFieldIndex(i) - inobject;
- if (target_index < 0) target_index += total_size;
- Handle<Object> box = isolate->factory()->NewHeapNumber(0);
- array->set(target_index, *box);
+ value = isolate->factory()->NewHeapNumber(0);
+ } else {
+ value = isolate->factory()->uninitialized_value();
}
+ int target_index = new_descriptors->GetFieldIndex(i) - inobject;
+ if (target_index < 0) target_index += total_size;
+ array->set(target_index, *value);
}
// From here on we cannot fail and we shouldn't GC anymore.
@@ -2442,6 +2253,11 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
int instance_size_delta = old_map->instance_size() - new_instance_size;
ASSERT(instance_size_delta >= 0);
Address address = object->address() + new_instance_size;
+
+ // The trimming is performed on a newly allocated object, which is on a
+ // fresly allocated page or on an already swept page. Hence, the sweeper
+ // thread can not get confused with the filler creation. No synchronization
+ // needed.
isolate->heap()->CreateFillerObjectAt(address, instance_size_delta);
// If there are properties in the new backing store, trim it to the correct
@@ -2451,26 +2267,22 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
object->set_properties(*array);
}
+ // The trimming is performed on a newly allocated object, which is on a
+ // fresly allocated page or on an already swept page. Hence, the sweeper
+ // thread can not get confused with the filler creation. No synchronization
+ // needed.
object->set_map(*new_map);
}
-Handle<TransitionArray> Map::AddTransition(Handle<Map> map,
- Handle<Name> key,
- Handle<Map> target,
- SimpleTransitionFlag flag) {
- CALL_HEAP_FUNCTION(map->GetIsolate(),
- map->AddTransition(*key, *target, flag),
- TransitionArray);
-}
-
-
void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
int modify_index,
Representation new_representation,
+ Handle<HeapType> new_field_type,
StoreMode store_mode) {
Handle<Map> new_map = Map::GeneralizeRepresentation(
- handle(object->map()), modify_index, new_representation, store_mode);
+ handle(object->map()), modify_index, new_representation,
+ new_field_type, store_mode);
if (object->map() == *new_map) return;
return MigrateToMap(object, new_map);
}
@@ -2491,20 +2303,26 @@ Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
StoreMode store_mode,
PropertyAttributes attributes,
const char* reason) {
+ Isolate* isolate = map->GetIsolate();
Handle<Map> new_map = Copy(map);
DescriptorArray* descriptors = new_map->instance_descriptors();
- descriptors->InitializeRepresentations(Representation::Tagged());
+ int length = descriptors->number_of_descriptors();
+ for (int i = 0; i < length; i++) {
+ descriptors->SetRepresentation(i, Representation::Tagged());
+ if (descriptors->GetDetails(i).type() == FIELD) {
+ descriptors->SetValue(i, HeapType::Any());
+ }
+ }
// Unless the instance is being migrated, ensure that modify_index is a field.
PropertyDetails details = descriptors->GetDetails(modify_index);
if (store_mode == FORCE_FIELD && details.type() != FIELD) {
- FieldDescriptor d(descriptors->GetKey(modify_index),
+ FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate),
new_map->NumberOfFields(),
attributes,
Representation::Tagged());
- d.SetSortedKeyIndex(details.pointer());
- descriptors->Set(modify_index, &d);
+ descriptors->Replace(modify_index, &d);
int unused_property_fields = new_map->unused_property_fields() - 1;
if (unused_property_fields < 0) {
unused_property_fields += JSObject::kFieldsAdded;
@@ -2513,11 +2331,15 @@ Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
}
if (FLAG_trace_generalization) {
+ HeapType* field_type = (details.type() == FIELD)
+ ? map->instance_descriptors()->GetFieldType(modify_index)
+ : NULL;
map->PrintGeneralization(stdout, reason, modify_index,
new_map->NumberOfOwnDescriptors(),
new_map->NumberOfOwnDescriptors(),
details.type() == CONSTANT && store_mode == FORCE_FIELD,
- Representation::Tagged(), Representation::Tagged());
+ details.representation(), Representation::Tagged(),
+ field_type, HeapType::Any());
}
return new_map;
}
@@ -2578,44 +2400,11 @@ Map* Map::FindRootMap() {
}
-// Returns NULL if the updated map is incompatible.
-Map* Map::FindUpdatedMap(int verbatim,
- int length,
- DescriptorArray* descriptors) {
- // This can only be called on roots of transition trees.
- ASSERT(GetBackPointer()->IsUndefined());
-
- Map* current = this;
-
- for (int i = verbatim; i < length; i++) {
- if (!current->HasTransitionArray()) break;
- Name* name = descriptors->GetKey(i);
- TransitionArray* transitions = current->transitions();
- int transition = transitions->Search(name);
- if (transition == TransitionArray::kNotFound) break;
- current = transitions->GetTarget(transition);
- PropertyDetails details = descriptors->GetDetails(i);
- PropertyDetails target_details =
- current->instance_descriptors()->GetDetails(i);
- if (details.attributes() != target_details.attributes()) return NULL;
- if (details.type() == CALLBACKS) {
- if (target_details.type() != CALLBACKS) return NULL;
- if (descriptors->GetValue(i) !=
- current->instance_descriptors()->GetValue(i)) {
- return NULL;
- }
- } else if (target_details.type() == CALLBACKS) {
- return NULL;
- }
- }
-
- return current;
-}
-
-
Map* Map::FindLastMatchMap(int verbatim,
int length,
DescriptorArray* descriptors) {
+ DisallowHeapAllocation no_allocation;
+
// This can only be called on roots of transition trees.
ASSERT(GetBackPointer()->IsUndefined());
@@ -2631,13 +2420,17 @@ Map* Map::FindLastMatchMap(int verbatim,
Map* next = transitions->GetTarget(transition);
DescriptorArray* next_descriptors = next->instance_descriptors();
- if (next_descriptors->GetValue(i) != descriptors->GetValue(i)) break;
-
PropertyDetails details = descriptors->GetDetails(i);
PropertyDetails next_details = next_descriptors->GetDetails(i);
if (details.type() != next_details.type()) break;
if (details.attributes() != next_details.attributes()) break;
if (!details.representation().Equals(next_details.representation())) break;
+ if (next_details.type() == FIELD) {
+ if (!descriptors->GetFieldType(i)->NowIs(
+ next_descriptors->GetFieldType(i))) break;
+ } else {
+ if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break;
+ }
current = next;
}
@@ -2645,6 +2438,100 @@ Map* Map::FindLastMatchMap(int verbatim,
}
+Map* Map::FindFieldOwner(int descriptor) {
+ DisallowHeapAllocation no_allocation;
+ ASSERT_EQ(FIELD, instance_descriptors()->GetDetails(descriptor).type());
+ Map* result = this;
+ while (true) {
+ Object* back = result->GetBackPointer();
+ if (back->IsUndefined()) break;
+ Map* parent = Map::cast(back);
+ if (parent->NumberOfOwnDescriptors() <= descriptor) break;
+ result = parent;
+ }
+ return result;
+}
+
+
+void Map::UpdateDescriptor(int descriptor_number, Descriptor* desc) {
+ DisallowHeapAllocation no_allocation;
+ if (HasTransitionArray()) {
+ TransitionArray* transitions = this->transitions();
+ for (int i = 0; i < transitions->number_of_transitions(); ++i) {
+ transitions->GetTarget(i)->UpdateDescriptor(descriptor_number, desc);
+ }
+ }
+ instance_descriptors()->Replace(descriptor_number, desc);;
+}
+
+
+// static
+Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1,
+ Handle<HeapType> type2,
+ Isolate* isolate) {
+ static const int kMaxClassesPerFieldType = 5;
+ if (type1->NowIs(type2)) return type2;
+ if (type2->NowIs(type1)) return type1;
+ if (type1->NowStable() && type2->NowStable()) {
+ Handle<HeapType> type = HeapType::Union(type1, type2, isolate);
+ if (type->NumClasses() <= kMaxClassesPerFieldType) {
+ ASSERT(type->NowStable());
+ ASSERT(type1->NowIs(type));
+ ASSERT(type2->NowIs(type));
+ return type;
+ }
+ }
+ return HeapType::Any(isolate);
+}
+
+
+// static
+void Map::GeneralizeFieldType(Handle<Map> map,
+ int modify_index,
+ Handle<HeapType> new_field_type) {
+ Isolate* isolate = map->GetIsolate();
+
+ // Check if we actually need to generalize the field type at all.
+ Handle<HeapType> old_field_type(
+ map->instance_descriptors()->GetFieldType(modify_index), isolate);
+ if (new_field_type->NowIs(old_field_type)) {
+ ASSERT(Map::GeneralizeFieldType(old_field_type,
+ new_field_type,
+ isolate)->NowIs(old_field_type));
+ return;
+ }
+
+ // Determine the field owner.
+ Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate);
+ Handle<DescriptorArray> descriptors(
+ field_owner->instance_descriptors(), isolate);
+ ASSERT_EQ(*old_field_type, descriptors->GetFieldType(modify_index));
+
+ // Determine the generalized new field type.
+ new_field_type = Map::GeneralizeFieldType(
+ old_field_type, new_field_type, isolate);
+
+ PropertyDetails details = descriptors->GetDetails(modify_index);
+ FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate),
+ descriptors->GetFieldIndex(modify_index),
+ new_field_type,
+ details.attributes(),
+ details.representation());
+ field_owner->UpdateDescriptor(modify_index, &d);
+ field_owner->dependent_code()->DeoptimizeDependentCodeGroup(
+ isolate, DependentCode::kFieldTypeGroup);
+
+ if (FLAG_trace_generalization) {
+ map->PrintGeneralization(
+ stdout, "field type generalization",
+ modify_index, map->NumberOfOwnDescriptors(),
+ map->NumberOfOwnDescriptors(), false,
+ details.representation(), details.representation(),
+ *old_field_type, *new_field_type);
+ }
+}
+
+
// Generalize the representation of the descriptor at |modify_index|.
// This method rewrites the transition tree to reflect the new change. To avoid
// high degrees over polymorphism, and to stabilize quickly, on every rewrite
@@ -2652,22 +2539,28 @@ Map* Map::FindLastMatchMap(int verbatim,
// (partial) version of the type in the transition tree.
// To do this, on each rewrite:
// - Search the root of the transition tree using FindRootMap.
-// - Find |updated|, the newest matching version of this map using
-// FindUpdatedMap. This uses the keys in the own map's descriptor array to
-// walk the transition tree.
-// - Merge/generalize the descriptor array of the current map and |updated|.
-// - Generalize the |modify_index| descriptor using |new_representation|.
-// - Walk the tree again starting from the root towards |updated|. Stop at
+// - Find |target_map|, the newest matching version of this map using the keys
+// in the |old_map|'s descriptor array to walk the transition tree.
+// - Merge/generalize the descriptor array of the |old_map| and |target_map|.
+// - Generalize the |modify_index| descriptor using |new_representation| and
+// |new_field_type|.
+// - Walk the tree again starting from the root towards |target_map|. Stop at
// |split_map|, the first map who's descriptor array does not match the merged
// descriptor array.
-// - If |updated| == |split_map|, |updated| is in the expected state. Return it.
-// - Otherwise, invalidate the outdated transition target from |updated|, and
+// - If |target_map| == |split_map|, |target_map| is in the expected state.
+// Return it.
+// - Otherwise, invalidate the outdated transition target from |target_map|, and
// replace its transition tree with a new branch for the updated descriptors.
Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
int modify_index,
Representation new_representation,
+ Handle<HeapType> new_field_type,
StoreMode store_mode) {
- Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
+ Isolate* isolate = old_map->GetIsolate();
+
+ Handle<DescriptorArray> old_descriptors(
+ old_map->instance_descriptors(), isolate);
+ int old_nof = old_map->NumberOfOwnDescriptors();
PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
Representation old_representation = old_details.representation();
@@ -2678,89 +2571,279 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
if (old_representation.IsNone() &&
!new_representation.IsNone() &&
!new_representation.IsDouble()) {
+ ASSERT(old_details.type() == FIELD);
+ ASSERT(old_descriptors->GetFieldType(modify_index)->NowIs(
+ HeapType::None()));
+ if (FLAG_trace_generalization) {
+ old_map->PrintGeneralization(
+ stdout, "uninitialized field",
+ modify_index, old_map->NumberOfOwnDescriptors(),
+ old_map->NumberOfOwnDescriptors(), false,
+ old_representation, new_representation,
+ old_descriptors->GetFieldType(modify_index), *new_field_type);
+ }
old_descriptors->SetRepresentation(modify_index, new_representation);
+ old_descriptors->SetValue(modify_index, *new_field_type);
return old_map;
}
- int descriptors = old_map->NumberOfOwnDescriptors();
- Handle<Map> root_map(old_map->FindRootMap());
-
// Check the state of the root map.
+ Handle<Map> root_map(old_map->FindRootMap(), isolate);
if (!old_map->EquivalentToForTransition(*root_map)) {
return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
old_details.attributes(), "not equivalent");
}
+ int root_nof = root_map->NumberOfOwnDescriptors();
+ if (modify_index < root_nof) {
+ PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
+ if ((old_details.type() != FIELD && store_mode == FORCE_FIELD) ||
+ (old_details.type() == FIELD &&
+ (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) ||
+ !new_representation.fits_into(old_details.representation())))) {
+ return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
+ old_details.attributes(), "root modification");
+ }
+ }
- int verbatim = root_map->NumberOfOwnDescriptors();
+ Handle<Map> target_map = root_map;
+ for (int i = root_nof; i < old_nof; ++i) {
+ int j = target_map->SearchTransition(old_descriptors->GetKey(i));
+ if (j == TransitionArray::kNotFound) break;
+ Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
+ Handle<DescriptorArray> tmp_descriptors = handle(
+ tmp_map->instance_descriptors(), isolate);
- if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) {
- return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
- old_details.attributes(), "root modification");
+ // Check if target map is incompatible.
+ PropertyDetails old_details = old_descriptors->GetDetails(i);
+ PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
+ PropertyType old_type = old_details.type();
+ PropertyType tmp_type = tmp_details.type();
+ if (tmp_details.attributes() != old_details.attributes() ||
+ ((tmp_type == CALLBACKS || old_type == CALLBACKS) &&
+ (tmp_type != old_type ||
+ tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) {
+ return CopyGeneralizeAllRepresentations(
+ old_map, modify_index, store_mode,
+ old_details.attributes(), "incompatible");
+ }
+ Representation old_representation = old_details.representation();
+ Representation tmp_representation = tmp_details.representation();
+ if (!old_representation.fits_into(tmp_representation) ||
+ (!new_representation.fits_into(tmp_representation) &&
+ modify_index == i)) {
+ break;
+ }
+ if (tmp_type == FIELD) {
+ // Generalize the field type as necessary.
+ Handle<HeapType> old_field_type = (old_type == FIELD)
+ ? handle(old_descriptors->GetFieldType(i), isolate)
+ : old_descriptors->GetValue(i)->OptimalType(
+ isolate, tmp_representation);
+ if (modify_index == i) {
+ old_field_type = GeneralizeFieldType(
+ new_field_type, old_field_type, isolate);
+ }
+ GeneralizeFieldType(tmp_map, i, old_field_type);
+ } else if (tmp_type == CONSTANT) {
+ if (old_type != CONSTANT ||
+ old_descriptors->GetConstant(i) != tmp_descriptors->GetConstant(i)) {
+ break;
+ }
+ } else {
+ ASSERT_EQ(tmp_type, old_type);
+ ASSERT_EQ(tmp_descriptors->GetValue(i), old_descriptors->GetValue(i));
+ }
+ target_map = tmp_map;
+ }
+
+ // Directly change the map if the target map is more general.
+ Handle<DescriptorArray> target_descriptors(
+ target_map->instance_descriptors(), isolate);
+ int target_nof = target_map->NumberOfOwnDescriptors();
+ if (target_nof == old_nof &&
+ (store_mode != FORCE_FIELD ||
+ target_descriptors->GetDetails(modify_index).type() == FIELD)) {
+ ASSERT(modify_index < target_nof);
+ ASSERT(new_representation.fits_into(
+ target_descriptors->GetDetails(modify_index).representation()));
+ ASSERT(target_descriptors->GetDetails(modify_index).type() != FIELD ||
+ new_field_type->NowIs(
+ target_descriptors->GetFieldType(modify_index)));
+ return target_map;
+ }
+
+ // Find the last compatible target map in the transition tree.
+ for (int i = target_nof; i < old_nof; ++i) {
+ int j = target_map->SearchTransition(old_descriptors->GetKey(i));
+ if (j == TransitionArray::kNotFound) break;
+ Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
+ Handle<DescriptorArray> tmp_descriptors(
+ tmp_map->instance_descriptors(), isolate);
+
+ // Check if target map is compatible.
+ PropertyDetails old_details = old_descriptors->GetDetails(i);
+ PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
+ if (tmp_details.attributes() != old_details.attributes() ||
+ ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) &&
+ (tmp_details.type() != old_details.type() ||
+ tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) {
+ return CopyGeneralizeAllRepresentations(
+ old_map, modify_index, store_mode,
+ old_details.attributes(), "incompatible");
+ }
+ target_map = tmp_map;
}
+ target_nof = target_map->NumberOfOwnDescriptors();
+ target_descriptors = handle(target_map->instance_descriptors(), isolate);
- Map* raw_updated = root_map->FindUpdatedMap(
- verbatim, descriptors, *old_descriptors);
- if (raw_updated == NULL) {
- return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
- old_details.attributes(), "incompatible");
+ // Allocate a new descriptor array large enough to hold the required
+ // descriptors, with minimally the exact same size as the old descriptor
+ // array.
+ int new_slack = Max(
+ old_nof, old_descriptors->number_of_descriptors()) - old_nof;
+ Handle<DescriptorArray> new_descriptors = DescriptorArray::Allocate(
+ isolate, old_nof, new_slack);
+ ASSERT(new_descriptors->length() > target_descriptors->length() ||
+ new_descriptors->NumberOfSlackDescriptors() > 0 ||
+ new_descriptors->number_of_descriptors() ==
+ old_descriptors->number_of_descriptors());
+ ASSERT(new_descriptors->number_of_descriptors() == old_nof);
+
+ // 0 -> |root_nof|
+ int current_offset = 0;
+ for (int i = 0; i < root_nof; ++i) {
+ PropertyDetails old_details = old_descriptors->GetDetails(i);
+ if (old_details.type() == FIELD) current_offset++;
+ Descriptor d(handle(old_descriptors->GetKey(i), isolate),
+ handle(old_descriptors->GetValue(i), isolate),
+ old_details);
+ new_descriptors->Set(i, &d);
}
- Handle<Map> updated(raw_updated);
- Handle<DescriptorArray> updated_descriptors(updated->instance_descriptors());
-
- int valid = updated->NumberOfOwnDescriptors();
+ // |root_nof| -> |target_nof|
+ for (int i = root_nof; i < target_nof; ++i) {
+ Handle<Name> target_key(target_descriptors->GetKey(i), isolate);
+ PropertyDetails old_details = old_descriptors->GetDetails(i);
+ PropertyDetails target_details = target_descriptors->GetDetails(i);
+ target_details = target_details.CopyWithRepresentation(
+ old_details.representation().generalize(
+ target_details.representation()));
+ if (modify_index == i) {
+ target_details = target_details.CopyWithRepresentation(
+ new_representation.generalize(target_details.representation()));
+ }
+ if (old_details.type() == FIELD ||
+ target_details.type() == FIELD ||
+ (modify_index == i && store_mode == FORCE_FIELD) ||
+ (target_descriptors->GetValue(i) != old_descriptors->GetValue(i))) {
+ Handle<HeapType> old_field_type = (old_details.type() == FIELD)
+ ? handle(old_descriptors->GetFieldType(i), isolate)
+ : old_descriptors->GetValue(i)->OptimalType(
+ isolate, target_details.representation());
+ Handle<HeapType> target_field_type = (target_details.type() == FIELD)
+ ? handle(target_descriptors->GetFieldType(i), isolate)
+ : target_descriptors->GetValue(i)->OptimalType(
+ isolate, target_details.representation());
+ target_field_type = GeneralizeFieldType(
+ target_field_type, old_field_type, isolate);
+ if (modify_index == i) {
+ target_field_type = GeneralizeFieldType(
+ target_field_type, new_field_type, isolate);
+ }
+ FieldDescriptor d(target_key,
+ current_offset++,
+ target_field_type,
+ target_details.attributes(),
+ target_details.representation());
+ new_descriptors->Set(i, &d);
+ } else {
+ ASSERT_NE(FIELD, target_details.type());
+ Descriptor d(target_key,
+ handle(target_descriptors->GetValue(i), isolate),
+ target_details);
+ new_descriptors->Set(i, &d);
+ }
+ }
- // Directly change the map if the target map is more general. Ensure that the
- // target type of the modify_index is a FIELD, unless we are migrating.
- if (updated_descriptors->IsMoreGeneralThan(
- verbatim, valid, descriptors, *old_descriptors) &&
- (store_mode == ALLOW_AS_CONSTANT ||
- updated_descriptors->GetDetails(modify_index).type() == FIELD)) {
- Representation updated_representation =
- updated_descriptors->GetDetails(modify_index).representation();
- if (new_representation.fits_into(updated_representation)) return updated;
+ // |target_nof| -> |old_nof|
+ for (int i = target_nof; i < old_nof; ++i) {
+ PropertyDetails old_details = old_descriptors->GetDetails(i);
+ Handle<Name> old_key(old_descriptors->GetKey(i), isolate);
+ if (modify_index == i) {
+ old_details = old_details.CopyWithRepresentation(
+ new_representation.generalize(old_details.representation()));
+ }
+ if (old_details.type() == FIELD) {
+ Handle<HeapType> old_field_type(
+ old_descriptors->GetFieldType(i), isolate);
+ if (modify_index == i) {
+ old_field_type = GeneralizeFieldType(
+ old_field_type, new_field_type, isolate);
+ }
+ FieldDescriptor d(old_key,
+ current_offset++,
+ old_field_type,
+ old_details.attributes(),
+ old_details.representation());
+ new_descriptors->Set(i, &d);
+ } else {
+ ASSERT(old_details.type() == CONSTANT || old_details.type() == CALLBACKS);
+ if (modify_index == i && store_mode == FORCE_FIELD) {
+ FieldDescriptor d(old_key,
+ current_offset++,
+ GeneralizeFieldType(
+ old_descriptors->GetValue(i)->OptimalType(
+ isolate, old_details.representation()),
+ new_field_type, isolate),
+ old_details.attributes(),
+ old_details.representation());
+ new_descriptors->Set(i, &d);
+ } else {
+ ASSERT_NE(FIELD, old_details.type());
+ Descriptor d(old_key,
+ handle(old_descriptors->GetValue(i), isolate),
+ old_details);
+ new_descriptors->Set(i, &d);
+ }
+ }
}
- Handle<DescriptorArray> new_descriptors = DescriptorArray::Merge(
- updated_descriptors, verbatim, valid, descriptors, modify_index,
- store_mode, old_descriptors);
- ASSERT(store_mode == ALLOW_AS_CONSTANT ||
- new_descriptors->GetDetails(modify_index).type() == FIELD);
+ new_descriptors->Sort();
- old_representation =
- new_descriptors->GetDetails(modify_index).representation();
- Representation updated_representation =
- new_representation.generalize(old_representation);
- if (!updated_representation.Equals(old_representation)) {
- new_descriptors->SetRepresentation(modify_index, updated_representation);
- }
+ ASSERT(store_mode != FORCE_FIELD ||
+ new_descriptors->GetDetails(modify_index).type() == FIELD);
Handle<Map> split_map(root_map->FindLastMatchMap(
- verbatim, descriptors, *new_descriptors));
+ root_nof, old_nof, *new_descriptors), isolate);
+ int split_nof = split_map->NumberOfOwnDescriptors();
+ ASSERT_NE(old_nof, split_nof);
- int split_descriptors = split_map->NumberOfOwnDescriptors();
- // This is shadowed by |updated_descriptors| being more general than
- // |old_descriptors|.
- ASSERT(descriptors != split_descriptors);
-
- int descriptor = split_descriptors;
split_map->DeprecateTarget(
- old_descriptors->GetKey(descriptor), *new_descriptors);
+ old_descriptors->GetKey(split_nof), *new_descriptors);
if (FLAG_trace_generalization) {
+ PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
+ PropertyDetails new_details = new_descriptors->GetDetails(modify_index);
+ Handle<HeapType> old_field_type = (old_details.type() == FIELD)
+ ? handle(old_descriptors->GetFieldType(modify_index), isolate)
+ : HeapType::Constant(handle(old_descriptors->GetValue(modify_index),
+ isolate), isolate);
+ Handle<HeapType> new_field_type = (new_details.type() == FIELD)
+ ? handle(new_descriptors->GetFieldType(modify_index), isolate)
+ : HeapType::Constant(handle(new_descriptors->GetValue(modify_index),
+ isolate), isolate);
old_map->PrintGeneralization(
- stdout, "", modify_index, descriptor, descriptors,
- old_descriptors->GetDetails(modify_index).type() == CONSTANT &&
- store_mode == FORCE_FIELD,
- old_representation, updated_representation);
+ stdout, "", modify_index, split_nof, old_nof,
+ old_details.type() == CONSTANT && store_mode == FORCE_FIELD,
+ old_details.representation(), new_details.representation(),
+ *old_field_type, *new_field_type);
}
// Add missing transitions.
Handle<Map> new_map = split_map;
- for (; descriptor < descriptors; descriptor++) {
- new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors);
+ for (int i = split_nof; i < old_nof; ++i) {
+ new_map = CopyInstallDescriptors(new_map, i, new_descriptors);
}
-
new_map->set_owns_descriptors(true);
return new_map;
}
@@ -2768,61 +2851,97 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
// Generalize the representation of all FIELD descriptors.
Handle<Map> Map::GeneralizeAllFieldRepresentations(
- Handle<Map> map,
- Representation new_representation) {
+ Handle<Map> map) {
Handle<DescriptorArray> descriptors(map->instance_descriptors());
- for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
- PropertyDetails details = descriptors->GetDetails(i);
- if (details.type() == FIELD) {
- map = GeneralizeRepresentation(map, i, new_representation, FORCE_FIELD);
+ for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) {
+ if (descriptors->GetDetails(i).type() == FIELD) {
+ map = GeneralizeRepresentation(map, i, Representation::Tagged(),
+ HeapType::Any(map->GetIsolate()),
+ FORCE_FIELD);
}
}
return map;
}
-Handle<Map> Map::CurrentMapForDeprecated(Handle<Map> map) {
+// static
+MaybeHandle<Map> Map::CurrentMapForDeprecated(Handle<Map> map) {
Handle<Map> proto_map(map);
while (proto_map->prototype()->IsJSObject()) {
Handle<JSObject> holder(JSObject::cast(proto_map->prototype()));
- if (holder->map()->is_deprecated()) {
- JSObject::TryMigrateInstance(holder);
- }
proto_map = Handle<Map>(holder->map());
+ if (proto_map->is_deprecated() && JSObject::TryMigrateInstance(holder)) {
+ proto_map = Handle<Map>(holder->map());
+ }
}
return CurrentMapForDeprecatedInternal(map);
}
-Handle<Map> Map::CurrentMapForDeprecatedInternal(Handle<Map> map) {
- if (!map->is_deprecated()) return map;
-
+// static
+MaybeHandle<Map> Map::CurrentMapForDeprecatedInternal(Handle<Map> old_map) {
DisallowHeapAllocation no_allocation;
- DescriptorArray* old_descriptors = map->instance_descriptors();
+ DisallowDeoptimization no_deoptimization(old_map->GetIsolate());
- int descriptors = map->NumberOfOwnDescriptors();
- Map* root_map = map->FindRootMap();
+ if (!old_map->is_deprecated()) return old_map;
// Check the state of the root map.
- if (!map->EquivalentToForTransition(root_map)) return Handle<Map>();
- int verbatim = root_map->NumberOfOwnDescriptors();
+ Map* root_map = old_map->FindRootMap();
+ if (!old_map->EquivalentToForTransition(root_map)) return MaybeHandle<Map>();
+ int root_nof = root_map->NumberOfOwnDescriptors();
+
+ int old_nof = old_map->NumberOfOwnDescriptors();
+ DescriptorArray* old_descriptors = old_map->instance_descriptors();
- Map* updated = root_map->FindUpdatedMap(
- verbatim, descriptors, old_descriptors);
- if (updated == NULL) return Handle<Map>();
+ Map* new_map = root_map;
+ for (int i = root_nof; i < old_nof; ++i) {
+ int j = new_map->SearchTransition(old_descriptors->GetKey(i));
+ if (j == TransitionArray::kNotFound) return MaybeHandle<Map>();
+ new_map = new_map->GetTransition(j);
+ DescriptorArray* new_descriptors = new_map->instance_descriptors();
- DescriptorArray* updated_descriptors = updated->instance_descriptors();
- int valid = updated->NumberOfOwnDescriptors();
- if (!updated_descriptors->IsMoreGeneralThan(
- verbatim, valid, descriptors, old_descriptors)) {
- return Handle<Map>();
- }
+ PropertyDetails new_details = new_descriptors->GetDetails(i);
+ PropertyDetails old_details = old_descriptors->GetDetails(i);
+ if (old_details.attributes() != new_details.attributes() ||
+ !old_details.representation().fits_into(new_details.representation())) {
+ return MaybeHandle<Map>();
+ }
+ PropertyType new_type = new_details.type();
+ PropertyType old_type = old_details.type();
+ Object* new_value = new_descriptors->GetValue(i);
+ Object* old_value = old_descriptors->GetValue(i);
+ switch (new_type) {
+ case FIELD:
+ if ((old_type == FIELD &&
+ !HeapType::cast(old_value)->NowIs(HeapType::cast(new_value))) ||
+ (old_type == CONSTANT &&
+ !HeapType::cast(new_value)->NowContains(old_value)) ||
+ (old_type == CALLBACKS &&
+ !HeapType::Any()->Is(HeapType::cast(new_value)))) {
+ return MaybeHandle<Map>();
+ }
+ break;
- return handle(updated);
+ case CONSTANT:
+ case CALLBACKS:
+ if (old_type != new_type || old_value != new_value) {
+ return MaybeHandle<Map>();
+ }
+ break;
+
+ case NORMAL:
+ case HANDLER:
+ case INTERCEPTOR:
+ case NONEXISTENT:
+ UNREACHABLE();
+ }
+ }
+ if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>();
+ return handle(new_map);
}
-Handle<Object> JSObject::SetPropertyWithInterceptor(
+MaybeHandle<Object> JSObject::SetPropertyWithInterceptor(
Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
@@ -2845,24 +2964,22 @@ Handle<Object> JSObject::SetPropertyWithInterceptor(
v8::Handle<v8::Value> result = args.Call(setter,
v8::Utils::ToLocal(name_string),
v8::Utils::ToLocal(value_unhole));
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (!result.IsEmpty()) return value;
}
- Handle<Object> result =
- SetPropertyPostInterceptor(object, name, value, attributes, strict_mode);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
- return result;
+ return SetPropertyPostInterceptor(
+ object, name, value, attributes, strict_mode);
}
-Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
- Handle<Name> name,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictMode strict_mode,
- StoreFromKeyed store_mode) {
+MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
+ Handle<Name> name,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode,
+ StoreFromKeyed store_mode) {
LookupResult result(object->GetIsolate());
- object->LocalLookup(*name, &result, true);
+ object->LocalLookup(name, &result, true);
if (!result.IsFound()) {
object->map()->LookupTransition(JSObject::cast(*object), *name, &result);
}
@@ -2871,34 +2988,18 @@ Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
}
-Handle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object,
- Handle<Object> structure,
- Handle<Name> name,
- Handle<Object> value,
- Handle<JSObject> holder,
- StrictMode strict_mode) {
+MaybeHandle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object,
+ Handle<Object> structure,
+ Handle<Name> name,
+ Handle<Object> value,
+ Handle<JSObject> holder,
+ StrictMode strict_mode) {
Isolate* isolate = object->GetIsolate();
// We should never get here to initialize a const with the hole
// value since a const declaration would conflict with the setter.
ASSERT(!value->IsTheHole());
-
- // To accommodate both the old and the new api we switch on the
- // data structure used to store the callbacks. Eventually foreign
- // callbacks should be phased out.
- if (structure->IsForeign()) {
- AccessorDescriptor* callback =
- reinterpret_cast<AccessorDescriptor*>(
- Handle<Foreign>::cast(structure)->foreign_address());
- CALL_AND_RETRY_OR_DIE(isolate,
- (callback->setter)(
- isolate, *object, *value, callback->data),
- break,
- return Handle<Object>());
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
- return value;
- }
-
+ ASSERT(!structure->IsForeign());
if (structure->IsExecutableAccessorInfo()) {
// api style callbacks
ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(*structure);
@@ -2908,8 +3009,7 @@ Handle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object,
isolate->factory()->NewTypeError("incompatible_method_receiver",
HandleVector(args,
ARRAY_SIZE(args)));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
// TODO(rossberg): Support symbols in the API.
if (name->IsSymbol()) return value;
@@ -2919,12 +3019,11 @@ Handle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object,
if (call_fun == NULL) return value;
Handle<String> key = Handle<String>::cast(name);
LOG(isolate, ApiNamedPropertyAccess("store", *object, *name));
- PropertyCallbackArguments args(
- isolate, data->data(), *object, JSObject::cast(*holder));
+ PropertyCallbackArguments args(isolate, data->data(), *object, *holder);
args.Call(call_fun,
v8::Utils::ToLocal(key),
v8::Utils::ToLocal(value));
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return value;
}
@@ -2940,8 +3039,7 @@ Handle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object,
Handle<Object> error =
isolate->factory()->NewTypeError("no_setter_in_callback",
HandleVector(args, 2));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
}
@@ -2951,17 +3049,16 @@ Handle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object,
}
UNREACHABLE();
- return Handle<Object>();
+ return MaybeHandle<Object>();
}
-Handle<Object> JSReceiver::SetPropertyWithDefinedSetter(
+MaybeHandle<Object> JSReceiver::SetPropertyWithDefinedSetter(
Handle<JSReceiver> object,
Handle<JSReceiver> setter,
Handle<Object> value) {
Isolate* isolate = object->GetIsolate();
-#ifdef ENABLE_DEBUGGER_SUPPORT
Debug* debug = isolate->debug();
// Handle stepping into a setter if step into is active.
// TODO(rossberg): should this apply to getters that are function proxies?
@@ -2969,19 +3066,17 @@ Handle<Object> JSReceiver::SetPropertyWithDefinedSetter(
debug->HandleStepIn(
Handle<JSFunction>::cast(setter), Handle<Object>::null(), 0, false);
}
-#endif
- bool has_pending_exception;
Handle<Object> argv[] = { value };
- Execution::Call(
- isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception);
- // Check for pending exception and return the result.
- if (has_pending_exception) return Handle<Object>();
+ RETURN_ON_EXCEPTION(
+ isolate,
+ Execution::Call(isolate, setter, object, ARRAY_SIZE(argv), argv),
+ Object);
return value;
}
-Handle<Object> JSObject::SetElementWithCallbackSetterInPrototypes(
+MaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
@@ -3022,12 +3117,13 @@ Handle<Object> JSObject::SetElementWithCallbackSetterInPrototypes(
}
-Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object,
- Handle<Name> name,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictMode strict_mode,
- bool* done) {
+MaybeHandle<Object> JSObject::SetPropertyViaPrototypes(
+ Handle<JSObject> object,
+ Handle<Name> name,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode,
+ bool* done) {
Isolate* isolate = object->GetIsolate();
*done = false;
@@ -3035,7 +3131,7 @@ Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object,
// accessor that wants to handle the property, or whether the property is
// read-only on the prototype chain.
LookupResult result(isolate);
- object->LookupRealNamedPropertyInPrototypes(*name, &result);
+ object->LookupRealNamedPropertyInPrototypes(name, &result);
if (result.IsFound()) {
switch (result.type()) {
case NORMAL:
@@ -3051,16 +3147,18 @@ Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object,
}
case CALLBACKS: {
*done = true;
- Handle<Object> callback_object(result.GetCallbackObject(), isolate);
- return SetPropertyWithCallback(object, callback_object, name, value,
- handle(result.holder()), strict_mode);
+ if (!result.IsReadOnly()) {
+ Handle<Object> callback_object(result.GetCallbackObject(), isolate);
+ return SetPropertyWithCallback(object, callback_object, name, value,
+ handle(result.holder()), strict_mode);
+ }
+ break;
}
case HANDLER: {
Handle<JSProxy> proxy(result.proxy());
return JSProxy::SetPropertyViaPrototypesWithHandler(
proxy, object, name, value, attributes, strict_mode, done);
}
- case TRANSITION:
case NONEXISTENT:
UNREACHABLE();
break;
@@ -3073,24 +3171,47 @@ Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object,
Handle<Object> args[] = { name, object };
Handle<Object> error = isolate->factory()->NewTypeError(
"strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
return isolate->factory()->the_hole_value();
}
void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
+ // Only supports adding slack to owned descriptors.
+ ASSERT(map->owns_descriptors());
+
Handle<DescriptorArray> descriptors(map->instance_descriptors());
+ int old_size = map->NumberOfOwnDescriptors();
if (slack <= descriptors->NumberOfSlackDescriptors()) return;
- int number_of_descriptors = descriptors->number_of_descriptors();
- Isolate* isolate = map->GetIsolate();
- Handle<DescriptorArray> new_descriptors =
- isolate->factory()->NewDescriptorArray(number_of_descriptors, slack);
- DescriptorArray::WhitenessWitness witness(*new_descriptors);
- for (int i = 0; i < number_of_descriptors; ++i) {
- new_descriptors->CopyFrom(i, *descriptors, i, witness);
+ Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
+ descriptors, old_size, slack);
+
+ if (old_size == 0) {
+ map->set_instance_descriptors(*new_descriptors);
+ return;
+ }
+
+ // If the source descriptors had an enum cache we copy it. This ensures
+ // that the maps to which we push the new descriptor array back can rely
+ // on a cache always being available once it is set. If the map has more
+ // enumerated descriptors than available in the original cache, the cache
+ // will be lazily replaced by the extended cache when needed.
+ if (descriptors->HasEnumCache()) {
+ new_descriptors->CopyEnumCacheFrom(*descriptors);
+ }
+
+ // Replace descriptors by new_descriptors in all maps that share it.
+ map->GetHeap()->incremental_marking()->RecordWrites(*descriptors);
+
+ Map* walk_map;
+ for (Object* current = map->GetBackPointer();
+ !current->IsUndefined();
+ current = walk_map->GetBackPointer()) {
+ walk_map = Map::cast(current);
+ if (walk_map->instance_descriptors() != *descriptors) break;
+ walk_map->set_instance_descriptors(*new_descriptors);
}
map->set_instance_descriptors(*new_descriptors);
@@ -3120,8 +3241,8 @@ static int AppendUniqueCallbacks(NeanderArray* callbacks,
// back to front so that the last callback with a given name takes
// precedence over previously added callbacks with that name.
for (int i = nof_callbacks - 1; i >= 0; i--) {
- AccessorInfo* entry = AccessorInfo::cast(callbacks->get(i));
- Name* key = Name::cast(entry->name());
+ Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks->get(i)));
+ Handle<Name> key(Name::cast(entry->name()));
// Check if a descriptor with this name already exists before writing.
if (!T::Contains(key, entry, valid_descriptors, array)) {
T::Insert(key, entry, valid_descriptors, array);
@@ -3134,16 +3255,18 @@ static int AppendUniqueCallbacks(NeanderArray* callbacks,
struct DescriptorArrayAppender {
typedef DescriptorArray Array;
- static bool Contains(Name* key,
- AccessorInfo* entry,
+ static bool Contains(Handle<Name> key,
+ Handle<AccessorInfo> entry,
int valid_descriptors,
Handle<DescriptorArray> array) {
- return array->Search(key, valid_descriptors) != DescriptorArray::kNotFound;
+ DisallowHeapAllocation no_gc;
+ return array->Search(*key, valid_descriptors) != DescriptorArray::kNotFound;
}
- static void Insert(Name* key,
- AccessorInfo* entry,
+ static void Insert(Handle<Name> key,
+ Handle<AccessorInfo> entry,
int valid_descriptors,
Handle<DescriptorArray> array) {
+ DisallowHeapAllocation no_gc;
CallbacksDescriptor desc(key, entry, entry->property_attributes());
array->Append(&desc);
}
@@ -3152,20 +3275,21 @@ struct DescriptorArrayAppender {
struct FixedArrayAppender {
typedef FixedArray Array;
- static bool Contains(Name* key,
- AccessorInfo* entry,
+ static bool Contains(Handle<Name> key,
+ Handle<AccessorInfo> entry,
int valid_descriptors,
Handle<FixedArray> array) {
for (int i = 0; i < valid_descriptors; i++) {
- if (key == AccessorInfo::cast(array->get(i))->name()) return true;
+ if (*key == AccessorInfo::cast(array->get(i))->name()) return true;
}
return false;
}
- static void Insert(Name* key,
- AccessorInfo* entry,
+ static void Insert(Handle<Name> key,
+ Handle<AccessorInfo> entry,
int valid_descriptors,
Handle<FixedArray> array) {
- array->set(valid_descriptors, entry);
+ DisallowHeapAllocation no_gc;
+ array->set(valid_descriptors, *entry);
}
};
@@ -3283,26 +3407,24 @@ bool Map::IsMapInArrayPrototypeChain() {
}
-static MaybeObject* AddMissingElementsTransitions(Map* map,
- ElementsKind to_kind) {
+static Handle<Map> AddMissingElementsTransitions(Handle<Map> map,
+ ElementsKind to_kind) {
ASSERT(IsTransitionElementsKind(map->elements_kind()));
- Map* current_map = map;
+ Handle<Map> current_map = map;
ElementsKind kind = map->elements_kind();
while (kind != to_kind && !IsTerminalElementsKind(kind)) {
kind = GetNextTransitionElementsKind(kind);
- MaybeObject* maybe_next_map =
- current_map->CopyAsElementsKind(kind, INSERT_TRANSITION);
- if (!maybe_next_map->To(&current_map)) return maybe_next_map;
+ current_map = Map::CopyAsElementsKind(
+ current_map, kind, INSERT_TRANSITION);
}
// In case we are exiting the fast elements kind system, just add the map in
// the end.
if (kind != to_kind) {
- MaybeObject* maybe_next_map =
- current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION);
- if (!maybe_next_map->To(&current_map)) return maybe_next_map;
+ current_map = Map::CopyAsElementsKind(
+ current_map, to_kind, INSERT_TRANSITION);
}
ASSERT(current_map->elements_kind() == to_kind);
@@ -3310,27 +3432,41 @@ static MaybeObject* AddMissingElementsTransitions(Map* map,
}
-Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
- ElementsKind to_kind) {
- Isolate* isolate = object->GetIsolate();
- CALL_HEAP_FUNCTION(isolate,
- object->GetElementsTransitionMap(isolate, to_kind),
- Map);
+Handle<Map> Map::TransitionElementsTo(Handle<Map> map,
+ ElementsKind to_kind) {
+ ElementsKind from_kind = map->elements_kind();
+ if (from_kind == to_kind) return map;
+
+ Isolate* isolate = map->GetIsolate();
+ Context* native_context = isolate->context()->native_context();
+ Object* maybe_array_maps = native_context->js_array_maps();
+ if (maybe_array_maps->IsFixedArray()) {
+ DisallowHeapAllocation no_gc;
+ FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
+ if (array_maps->get(from_kind) == *map) {
+ Object* maybe_transitioned_map = array_maps->get(to_kind);
+ if (maybe_transitioned_map->IsMap()) {
+ return handle(Map::cast(maybe_transitioned_map));
+ }
+ }
+ }
+
+ return TransitionElementsToSlow(map, to_kind);
}
-MaybeObject* JSObject::GetElementsTransitionMapSlow(ElementsKind to_kind) {
- Map* start_map = map();
- ElementsKind from_kind = start_map->elements_kind();
+Handle<Map> Map::TransitionElementsToSlow(Handle<Map> map,
+ ElementsKind to_kind) {
+ ElementsKind from_kind = map->elements_kind();
if (from_kind == to_kind) {
- return start_map;
+ return map;
}
bool allow_store_transition =
// Only remember the map transition if there is not an already existing
// non-matching element transition.
- !start_map->IsUndefined() && !start_map->is_shared() &&
+ !map->IsUndefined() && !map->is_shared() &&
IsTransitionElementsKind(from_kind);
// Only store fast element maps in ascending generality.
@@ -3341,24 +3477,16 @@ MaybeObject* JSObject::GetElementsTransitionMapSlow(ElementsKind to_kind) {
}
if (!allow_store_transition) {
- return start_map->CopyAsElementsKind(to_kind, OMIT_TRANSITION);
+ return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION);
}
- return start_map->AsElementsKind(to_kind);
+ return Map::AsElementsKind(map, to_kind);
}
-// TODO(ishell): Temporary wrapper until handlified.
// static
Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) {
- CALL_HEAP_FUNCTION(map->GetIsolate(),
- map->AsElementsKind(kind),
- Map);
-}
-
-
-MaybeObject* Map::AsElementsKind(ElementsKind kind) {
- Map* closest_map = FindClosestElementsTransition(this, kind);
+ Handle<Map> closest_map(FindClosestElementsTransition(*map, kind));
if (closest_map->elements_kind() == kind) {
return closest_map;
@@ -3368,7 +3496,15 @@ MaybeObject* Map::AsElementsKind(ElementsKind kind) {
}
-void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) {
+Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
+ ElementsKind to_kind) {
+ Handle<Map> map(object->map());
+ return Map::TransitionElementsTo(map, to_kind);
+}
+
+
+void JSObject::LocalLookupRealNamedProperty(Handle<Name> name,
+ LookupResult* result) {
DisallowHeapAllocation no_gc;
if (IsJSGlobalProxy()) {
Object* proto = GetPrototype();
@@ -3378,7 +3514,7 @@ void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) {
}
if (HasFastProperties()) {
- map()->LookupDescriptor(this, name, result);
+ map()->LookupDescriptor(this, *name, result);
// A property or a map transition was found. We return all of these result
// types because LocalLookupRealNamedProperty is used when setting
// properties where map transitions are handled.
@@ -3416,7 +3552,9 @@ void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) {
}
-void JSObject::LookupRealNamedProperty(Name* name, LookupResult* result) {
+void JSObject::LookupRealNamedProperty(Handle<Name> name,
+ LookupResult* result) {
+ DisallowHeapAllocation no_gc;
LocalLookupRealNamedProperty(name, result);
if (result->IsFound()) return;
@@ -3424,8 +3562,9 @@ void JSObject::LookupRealNamedProperty(Name* name, LookupResult* result) {
}
-void JSObject::LookupRealNamedPropertyInPrototypes(Name* name,
+void JSObject::LookupRealNamedPropertyInPrototypes(Handle<Name> name,
LookupResult* result) {
+ DisallowHeapAllocation no_gc;
Isolate* isolate = GetIsolate();
Heap* heap = isolate->heap();
for (Object* pt = GetPrototype();
@@ -3443,7 +3582,7 @@ void JSObject::LookupRealNamedPropertyInPrototypes(Name* name,
// We only need to deal with CALLBACKS and INTERCEPTORS
-Handle<Object> JSObject::SetPropertyWithFailedAccessCheck(
+MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck(
Handle<JSObject> object,
LookupResult* result,
Handle<Name> name,
@@ -3451,7 +3590,7 @@ Handle<Object> JSObject::SetPropertyWithFailedAccessCheck(
bool check_prototype,
StrictMode strict_mode) {
if (check_prototype && !result->IsProperty()) {
- object->LookupRealNamedPropertyInPrototypes(*name, result);
+ object->LookupRealNamedPropertyInPrototypes(name, result);
}
if (result->IsProperty()) {
@@ -3486,7 +3625,7 @@ Handle<Object> JSObject::SetPropertyWithFailedAccessCheck(
// Try lookup real named properties. Note that only property can be
// set is callbacks marked as ALL_CAN_WRITE on the prototype chain.
LookupResult r(object->GetIsolate());
- object->LookupRealNamedProperty(*name, &r);
+ object->LookupRealNamedProperty(name, &r);
if (r.IsProperty()) {
return SetPropertyWithFailedAccessCheck(object,
&r,
@@ -3505,19 +3644,19 @@ Handle<Object> JSObject::SetPropertyWithFailedAccessCheck(
}
Isolate* isolate = object->GetIsolate();
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return value;
}
-Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
- LookupResult* result,
- Handle<Name> key,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictMode strict_mode,
- StoreFromKeyed store_mode) {
+MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
+ LookupResult* result,
+ Handle<Name> key,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode,
+ StoreFromKeyed store_mode) {
if (result->IsHandler()) {
return JSProxy::SetPropertyWithHandler(handle(result->proxy()),
object, key, value, attributes, strict_mode);
@@ -3535,34 +3674,47 @@ bool JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name) {
if (name->IsSymbol()) return false;
Handle<Object> args[] = { name };
- Handle<Object> result = proxy->CallTrap(
- "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args);
- if (isolate->has_pending_exception()) return false;
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, result,
+ CallTrap(proxy,
+ "has",
+ isolate->derived_has_trap(),
+ ARRAY_SIZE(args),
+ args),
+ false);
return result->BooleanValue();
}
-Handle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy,
- Handle<JSReceiver> receiver,
- Handle<Name> name,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictMode strict_mode) {
+MaybeHandle<Object> JSProxy::SetPropertyWithHandler(
+ Handle<JSProxy> proxy,
+ Handle<JSReceiver> receiver,
+ Handle<Name> name,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode) {
Isolate* isolate = proxy->GetIsolate();
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (name->IsSymbol()) return value;
Handle<Object> args[] = { receiver, name, value };
- proxy->CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args);
- if (isolate->has_pending_exception()) return Handle<Object>();
+ RETURN_ON_EXCEPTION(
+ isolate,
+ CallTrap(proxy,
+ "set",
+ isolate->derived_set_trap(),
+ ARRAY_SIZE(args),
+ args),
+ Object);
return value;
}
-Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
+MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
Handle<JSProxy> proxy,
Handle<JSReceiver> receiver,
Handle<Name> name,
@@ -3581,9 +3733,15 @@ Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
*done = true; // except where redefined...
Handle<Object> args[] = { name };
- Handle<Object> result = proxy->CallTrap(
- "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args);
- if (isolate->has_pending_exception()) return Handle<Object>();
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ CallTrap(proxy,
+ "getPropertyDescriptor",
+ Handle<Object>(),
+ ARRAY_SIZE(args),
+ args),
+ Object);
if (result->IsUndefined()) {
*done = false;
@@ -3591,21 +3749,24 @@ Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
}
// Emulate [[GetProperty]] semantics for proxies.
- bool has_pending_exception;
Handle<Object> argv[] = { result };
- Handle<Object> desc = Execution::Call(
- isolate, isolate->to_complete_property_descriptor(), result,
- ARRAY_SIZE(argv), argv, &has_pending_exception);
- if (has_pending_exception) return Handle<Object>();
+ Handle<Object> desc;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, desc,
+ Execution::Call(isolate,
+ isolate->to_complete_property_descriptor(),
+ result,
+ ARRAY_SIZE(argv),
+ argv),
+ Object);
// [[GetProperty]] requires to check that all properties are configurable.
Handle<String> configurable_name =
isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("configurable_"));
- Handle<Object> configurable(
- v8::internal::GetProperty(isolate, desc, configurable_name));
- ASSERT(!isolate->has_pending_exception());
- ASSERT(configurable->IsTrue() || configurable->IsFalse());
+ Handle<Object> configurable =
+ Object::GetProperty(desc, configurable_name).ToHandleChecked();
+ ASSERT(configurable->IsBoolean());
if (configurable->IsFalse()) {
Handle<String> trap =
isolate->factory()->InternalizeOneByteString(
@@ -3613,8 +3774,7 @@ Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
Handle<Object> args[] = { handler, trap, name };
Handle<Object> error = isolate->factory()->NewTypeError(
"proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args)));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
ASSERT(configurable->IsTrue());
@@ -3622,33 +3782,29 @@ Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
Handle<String> hasWritable_name =
isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("hasWritable_"));
- Handle<Object> hasWritable(
- v8::internal::GetProperty(isolate, desc, hasWritable_name));
- ASSERT(!isolate->has_pending_exception());
- ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse());
+ Handle<Object> hasWritable =
+ Object::GetProperty(desc, hasWritable_name).ToHandleChecked();
+ ASSERT(hasWritable->IsBoolean());
if (hasWritable->IsTrue()) {
Handle<String> writable_name =
isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("writable_"));
- Handle<Object> writable(
- v8::internal::GetProperty(isolate, desc, writable_name));
- ASSERT(!isolate->has_pending_exception());
- ASSERT(writable->IsTrue() || writable->IsFalse());
+ Handle<Object> writable =
+ Object::GetProperty(desc, writable_name).ToHandleChecked();
+ ASSERT(writable->IsBoolean());
*done = writable->IsFalse();
if (!*done) return isolate->factory()->the_hole_value();
if (strict_mode == SLOPPY) return value;
Handle<Object> args[] = { name, receiver };
Handle<Object> error = isolate->factory()->NewTypeError(
"strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
// We have an AccessorDescriptor.
Handle<String> set_name = isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("set_"));
- Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_name));
- ASSERT(!isolate->has_pending_exception());
+ Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked();
if (!setter->IsUndefined()) {
// TODO(rossberg): nicer would be to cast to some JSCallable here...
return SetPropertyWithDefinedSetter(
@@ -3659,12 +3815,11 @@ Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
Handle<Object> args2[] = { name, proxy };
Handle<Object> error = isolate->factory()->NewTypeError(
"no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2)));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
-Handle<Object> JSProxy::DeletePropertyWithHandler(
+MaybeHandle<Object> JSProxy::DeletePropertyWithHandler(
Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) {
Isolate* isolate = proxy->GetIsolate();
@@ -3672,9 +3827,15 @@ Handle<Object> JSProxy::DeletePropertyWithHandler(
if (name->IsSymbol()) return isolate->factory()->false_value();
Handle<Object> args[] = { name };
- Handle<Object> result = proxy->CallTrap(
- "delete", Handle<Object>(), ARRAY_SIZE(args), args);
- if (isolate->has_pending_exception()) return Handle<Object>();
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ CallTrap(proxy,
+ "delete",
+ Handle<Object>(),
+ ARRAY_SIZE(args),
+ args),
+ Object);
bool result_bool = result->BooleanValue();
if (mode == STRICT_DELETION && !result_bool) {
@@ -3684,14 +3845,13 @@ Handle<Object> JSProxy::DeletePropertyWithHandler(
Handle<Object> args[] = { handler, trap_name };
Handle<Object> error = isolate->factory()->NewTypeError(
"handler_failed", HandleVector(args, ARRAY_SIZE(args)));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
return isolate->factory()->ToBoolean(result_bool);
}
-Handle<Object> JSProxy::DeleteElementWithHandler(
+MaybeHandle<Object> JSProxy::DeleteElementWithHandler(
Handle<JSProxy> proxy, uint32_t index, DeleteMode mode) {
Isolate* isolate = proxy->GetIsolate();
Handle<String> name = isolate->factory()->Uint32ToString(index);
@@ -3710,37 +3870,51 @@ PropertyAttributes JSProxy::GetPropertyAttributeWithHandler(
if (name->IsSymbol()) return ABSENT;
Handle<Object> args[] = { name };
- Handle<Object> result = proxy->CallTrap(
- "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args);
- if (isolate->has_pending_exception()) return NONE;
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, result,
+ proxy->CallTrap(proxy,
+ "getPropertyDescriptor",
+ Handle<Object>(),
+ ARRAY_SIZE(args),
+ args),
+ NONE);
if (result->IsUndefined()) return ABSENT;
- bool has_pending_exception;
Handle<Object> argv[] = { result };
- Handle<Object> desc = Execution::Call(
- isolate, isolate->to_complete_property_descriptor(), result,
- ARRAY_SIZE(argv), argv, &has_pending_exception);
- if (has_pending_exception) return NONE;
+ Handle<Object> desc;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, desc,
+ Execution::Call(isolate,
+ isolate->to_complete_property_descriptor(),
+ result,
+ ARRAY_SIZE(argv),
+ argv),
+ NONE);
// Convert result to PropertyAttributes.
Handle<String> enum_n = isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("enumerable_"));
- Handle<Object> enumerable(v8::internal::GetProperty(isolate, desc, enum_n));
- if (isolate->has_pending_exception()) return NONE;
+ Handle<Object> enumerable;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, enumerable, Object::GetProperty(desc, enum_n), NONE);
Handle<String> conf_n = isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("configurable_"));
- Handle<Object> configurable(v8::internal::GetProperty(isolate, desc, conf_n));
- if (isolate->has_pending_exception()) return NONE;
+ Handle<Object> configurable;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, configurable, Object::GetProperty(desc, conf_n), NONE);
Handle<String> writ_n = isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("writable_"));
- Handle<Object> writable(v8::internal::GetProperty(isolate, desc, writ_n));
- if (isolate->has_pending_exception()) return NONE;
+ Handle<Object> writable;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, writable, Object::GetProperty(desc, writ_n), NONE);
if (!writable->BooleanValue()) {
Handle<String> set_n = isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("set_"));
- Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_n));
- if (isolate->has_pending_exception()) return NONE;
+ Handle<Object> setter;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, setter, Object::GetProperty(desc, set_n), NONE);
writable = isolate->factory()->ToBoolean(!setter->IsUndefined());
}
@@ -3795,36 +3969,32 @@ void JSProxy::Fix(Handle<JSProxy> proxy) {
}
-MUST_USE_RESULT Handle<Object> JSProxy::CallTrap(const char* name,
- Handle<Object> derived,
- int argc,
- Handle<Object> argv[]) {
- Isolate* isolate = GetIsolate();
- Handle<Object> handler(this->handler(), isolate);
+MaybeHandle<Object> JSProxy::CallTrap(Handle<JSProxy> proxy,
+ const char* name,
+ Handle<Object> derived,
+ int argc,
+ Handle<Object> argv[]) {
+ Isolate* isolate = proxy->GetIsolate();
+ Handle<Object> handler(proxy->handler(), isolate);
Handle<String> trap_name = isolate->factory()->InternalizeUtf8String(name);
- Handle<Object> trap(v8::internal::GetProperty(isolate, handler, trap_name));
- if (isolate->has_pending_exception()) return trap;
+ Handle<Object> trap;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, trap,
+ Object::GetPropertyOrElement(handler, trap_name),
+ Object);
if (trap->IsUndefined()) {
if (derived.is_null()) {
Handle<Object> args[] = { handler, trap_name };
Handle<Object> error = isolate->factory()->NewTypeError(
"handler_trap_missing", HandleVector(args, ARRAY_SIZE(args)));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
trap = Handle<Object>(derived);
}
- bool threw;
- return Execution::Call(isolate, trap, handler, argc, argv, &threw);
-}
-
-
-// TODO(mstarzinger): Temporary wrapper until handlified.
-static Handle<Map> MapAsElementsKind(Handle<Map> map, ElementsKind kind) {
- CALL_HEAP_FUNCTION(map->GetIsolate(), map->AsElementsKind(kind), Map);
+ return Execution::Call(isolate, trap, handler, argc, argv);
}
@@ -3843,7 +4013,7 @@ void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
} else {
TransitionElementsKind(object, to_kind);
}
- map = MapAsElementsKind(map, to_kind);
+ map = Map::AsElementsKind(map, to_kind);
}
JSObject::MigrateToMap(object, map);
}
@@ -3855,7 +4025,9 @@ void JSObject::MigrateInstance(Handle<JSObject> object) {
// transition that matches the object. This achieves what is needed.
Handle<Map> original_map(object->map());
GeneralizeFieldRepresentation(
- object, 0, Representation::None(), ALLOW_AS_CONSTANT);
+ object, 0, Representation::None(),
+ HeapType::None(object->GetIsolate()),
+ ALLOW_AS_CONSTANT);
object->map()->set_migration_target(true);
if (FLAG_trace_migration) {
object->PrintInstanceMigration(stdout, *original_map, object->map());
@@ -3863,19 +4035,24 @@ void JSObject::MigrateInstance(Handle<JSObject> object) {
}
-Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) {
- Handle<Map> original_map(object->map());
- Handle<Map> new_map = Map::CurrentMapForDeprecatedInternal(original_map);
- if (new_map.is_null()) return Handle<Object>();
+// static
+bool JSObject::TryMigrateInstance(Handle<JSObject> object) {
+ Isolate* isolate = object->GetIsolate();
+ DisallowDeoptimization no_deoptimization(isolate);
+ Handle<Map> original_map(object->map(), isolate);
+ Handle<Map> new_map;
+ if (!Map::CurrentMapForDeprecatedInternal(original_map).ToHandle(&new_map)) {
+ return false;
+ }
JSObject::MigrateToMap(object, new_map);
if (FLAG_trace_migration) {
object->PrintInstanceMigration(stdout, *original_map, object->map());
}
- return object;
+ return true;
}
-Handle<Object> JSObject::SetPropertyUsingTransition(
+MaybeHandle<Object> JSObject::SetPropertyUsingTransition(
Handle<JSObject> object,
LookupResult* lookup,
Handle<Name> name,
@@ -3884,7 +4061,7 @@ Handle<Object> JSObject::SetPropertyUsingTransition(
Handle<Map> transition_map(lookup->GetTransitionTarget());
int descriptor = transition_map->LastAdded();
- DescriptorArray* descriptors = transition_map->instance_descriptors();
+ Handle<DescriptorArray> descriptors(transition_map->instance_descriptors());
PropertyDetails details = descriptors->GetDetails(descriptor);
if (details.type() == CALLBACKS || attributes != details.attributes()) {
@@ -3901,59 +4078,61 @@ Handle<Object> JSObject::SetPropertyUsingTransition(
// Keep the target CONSTANT if the same value is stored.
// TODO(verwaest): Also support keeping the placeholder
// (value->IsUninitialized) as constant.
- if (!value->FitsRepresentation(details.representation()) ||
- (details.type() == CONSTANT &&
- descriptors->GetValue(descriptor) != *value)) {
- transition_map = Map::GeneralizeRepresentation(transition_map,
- descriptor, value->OptimalRepresentation(), FORCE_FIELD);
+ if (!lookup->CanHoldValue(value)) {
+ Representation field_representation = value->OptimalRepresentation();
+ Handle<HeapType> field_type = value->OptimalType(
+ lookup->isolate(), field_representation);
+ transition_map = Map::GeneralizeRepresentation(
+ transition_map, descriptor,
+ field_representation, field_type, FORCE_FIELD);
}
- JSObject::MigrateToMap(object, transition_map);
+ JSObject::MigrateToNewProperty(object, transition_map, value);
+ return value;
+}
- // Reload.
- descriptors = transition_map->instance_descriptors();
- details = descriptors->GetDetails(descriptor);
- if (details.type() != FIELD) return value;
+void JSObject::MigrateToNewProperty(Handle<JSObject> object,
+ Handle<Map> map,
+ Handle<Object> value) {
+ JSObject::MigrateToMap(object, map);
+ if (map->GetLastDescriptorDetails().type() != FIELD) return;
+ object->WriteToField(map->LastAdded(), *value);
+}
- int field_index = descriptors->GetFieldIndex(descriptor);
+
+void JSObject::WriteToField(int descriptor, Object* value) {
+ DisallowHeapAllocation no_gc;
+
+ DescriptorArray* desc = map()->instance_descriptors();
+ PropertyDetails details = desc->GetDetails(descriptor);
+
+ ASSERT(details.type() == FIELD);
+
+ int field_index = desc->GetFieldIndex(descriptor);
if (details.representation().IsDouble()) {
// Nothing more to be done.
- if (value->IsUninitialized()) return value;
- HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index));
+ if (value->IsUninitialized()) return;
+ HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(field_index));
box->set_value(value->Number());
} else {
- object->FastPropertyAtPut(field_index, *value);
+ FastPropertyAtPut(field_index, value);
}
-
- return value;
}
static void SetPropertyToField(LookupResult* lookup,
- Handle<Name> name,
Handle<Object> value) {
- Representation representation = lookup->representation();
- if (!value->FitsRepresentation(representation) ||
- lookup->type() == CONSTANT) {
+ if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) {
+ Representation field_representation = value->OptimalRepresentation();
+ Handle<HeapType> field_type = value->OptimalType(
+ lookup->isolate(), field_representation);
JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()),
lookup->GetDescriptorIndex(),
- value->OptimalRepresentation(),
+ field_representation, field_type,
FORCE_FIELD);
- DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
- int descriptor = lookup->GetDescriptorIndex();
- representation = desc->GetDetails(descriptor).representation();
- }
-
- if (representation.IsDouble()) {
- HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
- lookup->GetFieldIndex().field_index()));
- storage->set_value(value->Number());
- return;
}
-
- lookup->holder()->FastPropertyAtPut(
- lookup->GetFieldIndex().field_index(), *value);
+ lookup->holder()->WriteToField(lookup->GetDescriptorIndex(), *value);
}
@@ -3974,7 +4153,8 @@ static void ConvertAndSetLocalProperty(LookupResult* lookup,
int descriptor_index = lookup->GetDescriptorIndex();
if (lookup->GetAttributes() == attributes) {
JSObject::GeneralizeFieldRepresentation(
- object, descriptor_index, Representation::Tagged(), FORCE_FIELD);
+ object, descriptor_index, Representation::Tagged(),
+ HeapType::Any(lookup->isolate()), FORCE_FIELD);
} else {
Handle<Map> old_map(object->map());
Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map,
@@ -3982,9 +4162,7 @@ static void ConvertAndSetLocalProperty(LookupResult* lookup,
JSObject::MigrateToMap(object, new_map);
}
- DescriptorArray* descriptors = object->map()->instance_descriptors();
- int index = descriptors->GetDetails(descriptor_index).field_index();
- object->FastPropertyAtPut(index, *value);
+ object->WriteToField(descriptor_index, *value);
}
@@ -3994,20 +4172,21 @@ static void SetPropertyToFieldWithAttributes(LookupResult* lookup,
PropertyAttributes attributes) {
if (lookup->GetAttributes() == attributes) {
if (value->IsUninitialized()) return;
- SetPropertyToField(lookup, name, value);
+ SetPropertyToField(lookup, value);
} else {
ConvertAndSetLocalProperty(lookup, name, value, attributes);
}
}
-Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object,
- LookupResult* lookup,
- Handle<Name> name,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictMode strict_mode,
- StoreFromKeyed store_mode) {
+MaybeHandle<Object> JSObject::SetPropertyForResult(
+ Handle<JSObject> object,
+ LookupResult* lookup,
+ Handle<Name> name,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode,
+ StoreFromKeyed store_mode) {
Isolate* isolate = object->GetIsolate();
// Make sure that the top context does not change when doing callbacks or
@@ -4024,7 +4203,7 @@ Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object,
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
+ if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) {
return SetPropertyWithFailedAccessCheck(object, lookup, name, value,
true, strict_mode);
}
@@ -4043,8 +4222,12 @@ Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object,
if (!lookup->IsProperty() && !object->IsJSContextExtensionObject()) {
bool done = false;
- Handle<Object> result_object = SetPropertyViaPrototypes(
- object, name, value, attributes, strict_mode, &done);
+ Handle<Object> result_object;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result_object,
+ SetPropertyViaPrototypes(
+ object, name, value, attributes, strict_mode, &done),
+ Object);
if (done) return result_object;
}
@@ -4059,8 +4242,7 @@ Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object,
Handle<Object> args[] = { name, object };
Handle<Object> error = isolate->factory()->NewTypeError(
"strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
} else {
return value;
}
@@ -4070,54 +4252,55 @@ Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object,
bool is_observed = object->map()->is_observed() &&
*name != isolate->heap()->hidden_string();
if (is_observed && lookup->IsDataProperty()) {
- old_value = Object::GetProperty(object, name);
- CHECK_NOT_EMPTY_HANDLE(isolate, old_value);
+ old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked();
}
// This is a real property that is not read-only, or it is a
// transition or null descriptor and there are no setters in the prototypes.
- Handle<Object> result = value;
- switch (lookup->type()) {
- case NORMAL:
- SetNormalizedProperty(handle(lookup->holder()), lookup, value);
- break;
- case FIELD:
- SetPropertyToField(lookup, name, value);
- break;
- case CONSTANT:
- // Only replace the constant if necessary.
- if (*value == lookup->GetConstant()) return value;
- SetPropertyToField(lookup, name, value);
- break;
- case CALLBACKS: {
- Handle<Object> callback_object(lookup->GetCallbackObject(), isolate);
- return SetPropertyWithCallback(object, callback_object, name, value,
- handle(lookup->holder()), strict_mode);
+ MaybeHandle<Object> maybe_result = value;
+ if (lookup->IsTransition()) {
+ maybe_result = SetPropertyUsingTransition(handle(lookup->holder()), lookup,
+ name, value, attributes);
+ } else {
+ switch (lookup->type()) {
+ case NORMAL:
+ SetNormalizedProperty(handle(lookup->holder()), lookup, value);
+ break;
+ case FIELD:
+ SetPropertyToField(lookup, value);
+ break;
+ case CONSTANT:
+ // Only replace the constant if necessary.
+ if (*value == lookup->GetConstant()) return value;
+ SetPropertyToField(lookup, value);
+ break;
+ case CALLBACKS: {
+ Handle<Object> callback_object(lookup->GetCallbackObject(), isolate);
+ return SetPropertyWithCallback(object, callback_object, name, value,
+ handle(lookup->holder()), strict_mode);
+ }
+ case INTERCEPTOR:
+ maybe_result = SetPropertyWithInterceptor(
+ handle(lookup->holder()), name, value, attributes, strict_mode);
+ break;
+ case HANDLER:
+ case NONEXISTENT:
+ UNREACHABLE();
}
- case INTERCEPTOR:
- result = SetPropertyWithInterceptor(handle(lookup->holder()), name, value,
- attributes, strict_mode);
- break;
- case TRANSITION:
- result = SetPropertyUsingTransition(handle(lookup->holder()), lookup,
- name, value, attributes);
- break;
- case HANDLER:
- case NONEXISTENT:
- UNREACHABLE();
}
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>());
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object);
if (is_observed) {
if (lookup->IsTransition()) {
EnqueueChangeRecord(object, "add", name, old_value);
} else {
LookupResult new_lookup(isolate);
- object->LocalLookup(*name, &new_lookup, true);
+ object->LocalLookup(name, &new_lookup, true);
if (new_lookup.IsDataProperty()) {
- Handle<Object> new_value = Object::GetProperty(object, name);
- CHECK_NOT_EMPTY_HANDLE(isolate, new_value);
+ Handle<Object> new_value =
+ Object::GetPropertyOrElement(object, name).ToHandleChecked();
if (!new_value->SameValue(*old_value)) {
EnqueueChangeRecord(object, "update", name, old_value);
}
@@ -4138,14 +4321,15 @@ Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object,
// Note that this method cannot be used to set the prototype of a function
// because ConvertDescriptorToField() which is called in "case CALLBACKS:"
// doesn't handle function prototypes correctly.
-Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
+MaybeHandle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
ValueType value_type,
StoreMode mode,
- ExtensibilityCheck extensibility_check) {
+ ExtensibilityCheck extensibility_check,
+ StoreFromKeyed store_from_keyed) {
Isolate* isolate = object->GetIsolate();
// Make sure that the top context does not change when doing callbacks or
@@ -4153,14 +4337,14 @@ Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
AssertNoContextChange ncc(isolate);
LookupResult lookup(isolate);
- object->LocalLookup(*name, &lookup, true);
+ object->LocalLookup(name, &lookup, true);
if (!lookup.IsFound()) {
object->map()->LookupTransition(*object, *name, &lookup);
}
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
+ if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) {
return SetPropertyWithFailedAccessCheck(object, &lookup, name, value,
false, SLOPPY);
}
@@ -4174,9 +4358,9 @@ Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
name, value, attributes, value_type, mode, extensibility_check);
}
- if (lookup.IsFound() &&
- (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) {
- object->LocalLookupRealNamedProperty(*name, &lookup);
+ if (lookup.IsInterceptor() ||
+ (lookup.IsDescriptorOrDictionary() && lookup.type() == CALLBACKS)) {
+ object->LocalLookupRealNamedProperty(name, &lookup);
}
// Check for accessor in prototype chain removed here in clone.
@@ -4186,7 +4370,7 @@ Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
? OMIT_TRANSITION : INSERT_TRANSITION;
// Neither properties nor transitions found.
return AddProperty(object, name, value, attributes, SLOPPY,
- MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag);
+ store_from_keyed, extensibility_check, value_type, mode, flag);
}
Handle<Object> old_value = isolate->factory()->the_hole_value();
@@ -4195,40 +4379,42 @@ Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
*name != isolate->heap()->hidden_string();
if (is_observed && lookup.IsProperty()) {
if (lookup.IsDataProperty()) {
- old_value = Object::GetProperty(object, name);
- CHECK_NOT_EMPTY_HANDLE(isolate, old_value);
+ old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked();
}
old_attributes = lookup.GetAttributes();
}
// Check of IsReadOnly removed from here in clone.
- switch (lookup.type()) {
- case NORMAL:
- ReplaceSlowProperty(object, name, value, attributes);
- break;
- case FIELD:
- SetPropertyToFieldWithAttributes(&lookup, name, value, attributes);
- break;
- case CONSTANT:
- // Only replace the constant if necessary.
- if (lookup.GetAttributes() != attributes ||
- *value != lookup.GetConstant()) {
+ if (lookup.IsTransition()) {
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ SetPropertyUsingTransition(
+ handle(lookup.holder()), &lookup, name, value, attributes),
+ Object);
+ } else {
+ switch (lookup.type()) {
+ case NORMAL:
+ ReplaceSlowProperty(object, name, value, attributes);
+ break;
+ case FIELD:
SetPropertyToFieldWithAttributes(&lookup, name, value, attributes);
- }
- break;
- case CALLBACKS:
- ConvertAndSetLocalProperty(&lookup, name, value, attributes);
- break;
- case TRANSITION: {
- Handle<Object> result = SetPropertyUsingTransition(
- handle(lookup.holder()), &lookup, name, value, attributes);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>());
- break;
+ break;
+ case CONSTANT:
+ // Only replace the constant if necessary.
+ if (lookup.GetAttributes() != attributes ||
+ *value != lookup.GetConstant()) {
+ SetPropertyToFieldWithAttributes(&lookup, name, value, attributes);
+ }
+ break;
+ case CALLBACKS:
+ ConvertAndSetLocalProperty(&lookup, name, value, attributes);
+ break;
+ case NONEXISTENT:
+ case HANDLER:
+ case INTERCEPTOR:
+ UNREACHABLE();
}
- case NONEXISTENT:
- case HANDLER:
- case INTERCEPTOR:
- UNREACHABLE();
}
if (is_observed) {
@@ -4238,11 +4424,11 @@ Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes(
EnqueueChangeRecord(object, "reconfigure", name, old_value);
} else {
LookupResult new_lookup(isolate);
- object->LocalLookup(*name, &new_lookup, true);
+ object->LocalLookup(name, &new_lookup, true);
bool value_changed = false;
if (new_lookup.IsDataProperty()) {
- Handle<Object> new_value = Object::GetProperty(object, name);
- CHECK_NOT_EMPTY_HANDLE(isolate, new_value);
+ Handle<Object> new_value =
+ Object::GetPropertyOrElement(object, name).ToHandleChecked();
value_changed = !old_value->SameValue(*new_value);
}
if (new_lookup.GetAttributes() != old_attributes) {
@@ -4266,7 +4452,7 @@ PropertyAttributes JSObject::GetPropertyAttributePostInterceptor(
// Check local property, ignore interceptor.
Isolate* isolate = object->GetIsolate();
LookupResult result(isolate);
- object->LocalLookupRealNamedProperty(*name, &result);
+ object->LocalLookupRealNamedProperty(name, &result);
if (result.IsFound()) return result.GetAttributes();
if (continue_search) {
@@ -4335,7 +4521,7 @@ PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver(
}
// Named property.
LookupResult lookup(object->GetIsolate());
- object->Lookup(*key, &lookup);
+ object->Lookup(key, &lookup);
return GetPropertyAttributeForResult(object, receiver, &lookup, key, true);
}
@@ -4350,7 +4536,7 @@ PropertyAttributes JSReceiver::GetPropertyAttributeForResult(
if (object->IsAccessCheckNeeded()) {
Heap* heap = object->GetHeap();
Handle<JSObject> obj = Handle<JSObject>::cast(object);
- if (!heap->isolate()->MayNamedAccessWrapper(obj, name, v8::ACCESS_HAS)) {
+ if (!heap->isolate()->MayNamedAccess(obj, name, v8::ACCESS_HAS)) {
return JSObject::GetPropertyAttributeWithFailedAccessCheck(
obj, lookup, name, continue_search);
}
@@ -4372,7 +4558,6 @@ PropertyAttributes JSReceiver::GetPropertyAttributeForResult(
Handle<JSObject>::cast(receiver),
name,
continue_search);
- case TRANSITION:
case NONEXISTENT:
UNREACHABLE();
}
@@ -4390,7 +4575,7 @@ PropertyAttributes JSReceiver::GetLocalPropertyAttribute(
}
// Named property.
LookupResult lookup(object->GetIsolate());
- object->LocalLookup(*name, &lookup, true);
+ object->LocalLookup(name, &lookup, true);
return GetPropertyAttributeForResult(object, object, &lookup, name, false);
}
@@ -4404,8 +4589,9 @@ PropertyAttributes JSObject::GetElementAttributeWithReceiver(
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
+ if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
+ // TODO(yangguo): Issue 3269, check for scheduled exception missing?
return ABSENT;
}
}
@@ -4473,7 +4659,7 @@ PropertyAttributes JSObject::GetElementAttributeWithoutInterceptor(
uint32_t index,
bool continue_search) {
PropertyAttributes attr = object->GetElementsAccessor()->GetAttributes(
- *receiver, *object, index);
+ receiver, object, index);
if (attr != ABSENT) return attr;
// Handle [] on String objects.
@@ -4495,49 +4681,30 @@ PropertyAttributes JSObject::GetElementAttributeWithoutInterceptor(
}
-Handle<Map> NormalizedMapCache::Get(Handle<NormalizedMapCache> cache,
- Handle<JSObject> obj,
- PropertyNormalizationMode mode) {
- int index = obj->map()->Hash() % kEntries;
- Handle<Object> result = handle(cache->get(index), cache->GetIsolate());
- if (result->IsMap() &&
- Handle<Map>::cast(result)->EquivalentToForNormalization(obj->map(),
- mode)) {
-#ifdef VERIFY_HEAP
- if (FLAG_verify_heap) {
- Handle<Map>::cast(result)->SharedMapVerify();
- }
-#endif
-#ifdef ENABLE_SLOW_ASSERTS
- if (FLAG_enable_slow_asserts) {
- // The cached map should match newly created normalized map bit-by-bit,
- // except for the code cache, which can contain some ics which can be
- // applied to the shared map.
- Handle<Map> fresh = Map::CopyNormalized(handle(obj->map()), mode,
- SHARED_NORMALIZED_MAP);
+Handle<NormalizedMapCache> NormalizedMapCache::New(Isolate* isolate) {
+ Handle<FixedArray> array(
+ isolate->factory()->NewFixedArray(kEntries, TENURED));
+ return Handle<NormalizedMapCache>::cast(array);
+}
- ASSERT(memcmp(fresh->address(),
- Handle<Map>::cast(result)->address(),
- Map::kCodeCacheOffset) == 0);
- STATIC_ASSERT(Map::kDependentCodeOffset ==
- Map::kCodeCacheOffset + kPointerSize);
- int offset = Map::kDependentCodeOffset + kPointerSize;
- ASSERT(memcmp(fresh->address() + offset,
- Handle<Map>::cast(result)->address() + offset,
- Map::kSize - offset) == 0);
- }
-#endif
- return Handle<Map>::cast(result);
+
+MaybeHandle<Map> NormalizedMapCache::Get(Handle<Map> fast_map,
+ PropertyNormalizationMode mode) {
+ DisallowHeapAllocation no_gc;
+ Object* value = FixedArray::get(GetIndex(fast_map));
+ if (!value->IsMap() ||
+ !Map::cast(value)->EquivalentToForNormalization(*fast_map, mode)) {
+ return MaybeHandle<Map>();
}
+ return handle(Map::cast(value));
+}
- Isolate* isolate = cache->GetIsolate();
- Handle<Map> map = Map::CopyNormalized(handle(obj->map()), mode,
- SHARED_NORMALIZED_MAP);
- ASSERT(map->is_dictionary_map());
- cache->set(index, *map);
- isolate->counters()->normalized_maps()->Increment();
- return map;
+void NormalizedMapCache::Set(Handle<Map> fast_map,
+ Handle<Map> normalized_map) {
+ DisallowHeapAllocation no_gc;
+ ASSERT(normalized_map->is_dictionary_map());
+ FixedArray::set(GetIndex(fast_map), *normalized_map);
}
@@ -4570,6 +4737,7 @@ void JSObject::NormalizeProperties(Handle<JSObject> object,
Isolate* isolate = object->GetIsolate();
HandleScope scope(isolate);
Handle<Map> map(object->map());
+ Handle<Map> new_map = Map::Normalize(map, mode);
// Allocate new content.
int real_size = map->NumberOfOwnDescriptors();
@@ -4580,7 +4748,7 @@ void JSObject::NormalizeProperties(Handle<JSObject> object,
property_count += 2; // Make space for two more properties.
}
Handle<NameDictionary> dictionary =
- isolate->factory()->NewNameDictionary(property_count);
+ NameDictionary::New(isolate, property_count);
Handle<DescriptorArray> descs(map->instance_descriptors());
for (int i = 0; i < real_size; i++) {
@@ -4591,7 +4759,7 @@ void JSObject::NormalizeProperties(Handle<JSObject> object,
Handle<Object> value(descs->GetConstant(i), isolate);
PropertyDetails d = PropertyDetails(
details.attributes(), NORMAL, i + 1);
- dictionary = NameDictionaryAdd(dictionary, key, value, d);
+ dictionary = NameDictionary::Add(dictionary, key, value, d);
break;
}
case FIELD: {
@@ -4600,7 +4768,7 @@ void JSObject::NormalizeProperties(Handle<JSObject> object,
object->RawFastPropertyAt(descs->GetFieldIndex(i)), isolate);
PropertyDetails d =
PropertyDetails(details.attributes(), NORMAL, i + 1);
- dictionary = NameDictionaryAdd(dictionary, key, value, d);
+ dictionary = NameDictionary::Add(dictionary, key, value, d);
break;
}
case CALLBACKS: {
@@ -4608,14 +4776,13 @@ void JSObject::NormalizeProperties(Handle<JSObject> object,
Handle<Object> value(descs->GetCallbacksObject(i), isolate);
PropertyDetails d = PropertyDetails(
details.attributes(), CALLBACKS, i + 1);
- dictionary = NameDictionaryAdd(dictionary, key, value, d);
+ dictionary = NameDictionary::Add(dictionary, key, value, d);
break;
}
case INTERCEPTOR:
break;
case HANDLER:
case NORMAL:
- case TRANSITION:
case NONEXISTENT:
UNREACHABLE();
break;
@@ -4625,11 +4792,6 @@ void JSObject::NormalizeProperties(Handle<JSObject> object,
// Copy the next enumeration index from instance descriptor.
dictionary->SetNextEnumerationIndex(real_size + 1);
- Handle<NormalizedMapCache> cache(
- isolate->context()->native_context()->normalized_map_cache());
- Handle<Map> new_map = NormalizedMapCache::Get(cache, object, mode);
- ASSERT(new_map->is_dictionary_map());
-
// From here on we cannot fail and we shouldn't GC anymore.
DisallowHeapAllocation no_allocation;
@@ -4644,8 +4806,9 @@ void JSObject::NormalizeProperties(Handle<JSObject> object,
-instance_size_delta,
Heap::FROM_MUTATOR);
- object->set_map(*new_map);
- map->NotifyLeafMapLayoutChange();
+ // We are storing the new map using release store after creating a filler for
+ // the left-over space to avoid races with the sweeper thread.
+ object->synchronized_set_map(*new_map);
object->set_properties(*dictionary);
@@ -4664,10 +4827,162 @@ void JSObject::TransformToFastProperties(Handle<JSObject> object,
int unused_property_fields) {
if (object->HasFastProperties()) return;
ASSERT(!object->IsGlobalObject());
- CALL_HEAP_FUNCTION_VOID(
- object->GetIsolate(),
- object->property_dictionary()->TransformPropertiesToFastFor(
- *object, unused_property_fields));
+ Isolate* isolate = object->GetIsolate();
+ Factory* factory = isolate->factory();
+ Handle<NameDictionary> dictionary(object->property_dictionary());
+
+ // Make sure we preserve dictionary representation if there are too many
+ // descriptors.
+ int number_of_elements = dictionary->NumberOfElements();
+ if (number_of_elements > kMaxNumberOfDescriptors) return;
+
+ if (number_of_elements != dictionary->NextEnumerationIndex()) {
+ NameDictionary::DoGenerateNewEnumerationIndices(dictionary);
+ }
+
+ int instance_descriptor_length = 0;
+ int number_of_fields = 0;
+
+ // Compute the length of the instance descriptor.
+ int capacity = dictionary->Capacity();
+ for (int i = 0; i < capacity; i++) {
+ Object* k = dictionary->KeyAt(i);
+ if (dictionary->IsKey(k)) {
+ Object* value = dictionary->ValueAt(i);
+ PropertyType type = dictionary->DetailsAt(i).type();
+ ASSERT(type != FIELD);
+ instance_descriptor_length++;
+ if (type == NORMAL && !value->IsJSFunction()) {
+ number_of_fields += 1;
+ }
+ }
+ }
+
+ int inobject_props = object->map()->inobject_properties();
+
+ // Allocate new map.
+ Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
+ new_map->set_dictionary_map(false);
+
+ if (instance_descriptor_length == 0) {
+ DisallowHeapAllocation no_gc;
+ ASSERT_LE(unused_property_fields, inobject_props);
+ // Transform the object.
+ new_map->set_unused_property_fields(inobject_props);
+ object->set_map(*new_map);
+ object->set_properties(isolate->heap()->empty_fixed_array());
+ // Check that it really works.
+ ASSERT(object->HasFastProperties());
+ return;
+ }
+
+ // Allocate the instance descriptor.
+ Handle<DescriptorArray> descriptors = DescriptorArray::Allocate(
+ isolate, instance_descriptor_length);
+
+ int number_of_allocated_fields =
+ number_of_fields + unused_property_fields - inobject_props;
+ if (number_of_allocated_fields < 0) {
+ // There is enough inobject space for all fields (including unused).
+ number_of_allocated_fields = 0;
+ unused_property_fields = inobject_props - number_of_fields;
+ }
+
+ // Allocate the fixed array for the fields.
+ Handle<FixedArray> fields = factory->NewFixedArray(
+ number_of_allocated_fields);
+
+ // Fill in the instance descriptor and the fields.
+ int current_offset = 0;
+ for (int i = 0; i < capacity; i++) {
+ Object* k = dictionary->KeyAt(i);
+ if (dictionary->IsKey(k)) {
+ Object* value = dictionary->ValueAt(i);
+ Handle<Name> key;
+ if (k->IsSymbol()) {
+ key = handle(Symbol::cast(k));
+ } else {
+ // Ensure the key is a unique name before writing into the
+ // instance descriptor.
+ key = factory->InternalizeString(handle(String::cast(k)));
+ }
+
+ PropertyDetails details = dictionary->DetailsAt(i);
+ int enumeration_index = details.dictionary_index();
+ PropertyType type = details.type();
+
+ if (value->IsJSFunction()) {
+ ConstantDescriptor d(key,
+ handle(value, isolate),
+ details.attributes());
+ descriptors->Set(enumeration_index - 1, &d);
+ } else if (type == NORMAL) {
+ if (current_offset < inobject_props) {
+ object->InObjectPropertyAtPut(current_offset,
+ value,
+ UPDATE_WRITE_BARRIER);
+ } else {
+ int offset = current_offset - inobject_props;
+ fields->set(offset, value);
+ }
+ FieldDescriptor d(key,
+ current_offset++,
+ details.attributes(),
+ // TODO(verwaest): value->OptimalRepresentation();
+ Representation::Tagged());
+ descriptors->Set(enumeration_index - 1, &d);
+ } else if (type == CALLBACKS) {
+ CallbacksDescriptor d(key,
+ handle(value, isolate),
+ details.attributes());
+ descriptors->Set(enumeration_index - 1, &d);
+ } else {
+ UNREACHABLE();
+ }
+ }
+ }
+ ASSERT(current_offset == number_of_fields);
+
+ descriptors->Sort();
+
+ DisallowHeapAllocation no_gc;
+ new_map->InitializeDescriptors(*descriptors);
+ new_map->set_unused_property_fields(unused_property_fields);
+
+ // Transform the object.
+ object->set_map(*new_map);
+
+ object->set_properties(*fields);
+ ASSERT(object->IsJSObject());
+
+ // Check that it really works.
+ ASSERT(object->HasFastProperties());
+}
+
+
+void JSObject::ResetElements(Handle<JSObject> object) {
+ if (object->map()->is_observed()) {
+ // Maintain invariant that observed elements are always in dictionary mode.
+ Isolate* isolate = object->GetIsolate();
+ Factory* factory = isolate->factory();
+ Handle<SeededNumberDictionary> dictionary =
+ SeededNumberDictionary::New(isolate, 0);
+ if (object->map() == *factory->sloppy_arguments_elements_map()) {
+ FixedArray::cast(object->elements())->set(1, *dictionary);
+ } else {
+ object->set_elements(*dictionary);
+ }
+ return;
+ }
+
+ ElementsKind elements_kind = GetInitialFastElementsKind();
+ if (!FLAG_smi_only_arrays) {
+ elements_kind = FastSmiToObjectElementsKind(elements_kind);
+ }
+ Handle<Map> map = JSObject::GetElementsTransitionMap(object, elements_kind);
+ DisallowHeapAllocation no_gc;
+ Handle<FixedArrayBase> elements(map->GetInitialElements());
+ JSObject::SetMapAndElements(object, map, elements);
}
@@ -4706,7 +5021,6 @@ Handle<SeededNumberDictionary> JSObject::NormalizeElements(
ASSERT(!object->HasExternalArrayElements() &&
!object->HasFixedTypedArrayElements());
Isolate* isolate = object->GetIsolate();
- Factory* factory = isolate->factory();
// Find the backing store.
Handle<FixedArrayBase> array(FixedArrayBase::cast(object->elements()));
@@ -4729,7 +5043,7 @@ Handle<SeededNumberDictionary> JSObject::NormalizeElements(
int used_elements = 0;
object->GetElementsCapacityAndUsage(&old_capacity, &used_elements);
Handle<SeededNumberDictionary> dictionary =
- factory->NewSeededNumberDictionary(used_elements);
+ SeededNumberDictionary::New(isolate, used_elements);
dictionary = CopyFastElementsToDictionary(array, length, dictionary);
@@ -4761,9 +5075,7 @@ Handle<SeededNumberDictionary> JSObject::NormalizeElements(
}
-Smi* JSReceiver::GenerateIdentityHash() {
- Isolate* isolate = GetIsolate();
-
+static Smi* GenerateIdentityHash(Isolate* isolate) {
int hash_value;
int attempts = 0;
do {
@@ -4779,33 +5091,51 @@ Smi* JSReceiver::GenerateIdentityHash() {
void JSObject::SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash) {
+ ASSERT(!object->IsJSGlobalProxy());
Isolate* isolate = object->GetIsolate();
SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash);
}
+template<typename ProxyType>
+static Handle<Object> GetOrCreateIdentityHashHelper(Handle<ProxyType> proxy) {
+ Isolate* isolate = proxy->GetIsolate();
+
+ Handle<Object> hash(proxy->hash(), isolate);
+ if (hash->IsSmi()) return hash;
+
+ hash = handle(GenerateIdentityHash(isolate), isolate);
+ proxy->set_hash(*hash);
+ return hash;
+}
+
+
Object* JSObject::GetIdentityHash() {
- Object* stored_value = GetHiddenProperty(GetHeap()->identity_hash_string());
- return stored_value->IsSmi() ? stored_value : GetHeap()->undefined_value();
+ DisallowHeapAllocation no_gc;
+ Isolate* isolate = GetIsolate();
+ if (IsJSGlobalProxy()) {
+ return JSGlobalProxy::cast(this)->hash();
+ }
+ Object* stored_value =
+ GetHiddenProperty(isolate->factory()->identity_hash_string());
+ return stored_value->IsSmi()
+ ? stored_value
+ : isolate->heap()->undefined_value();
}
Handle<Object> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) {
- Handle<Object> hash(object->GetIdentityHash(), object->GetIsolate());
- if (hash->IsSmi())
- return hash;
+ if (object->IsJSGlobalProxy()) {
+ return GetOrCreateIdentityHashHelper(Handle<JSGlobalProxy>::cast(object));
+ }
Isolate* isolate = object->GetIsolate();
- hash = handle(object->GenerateIdentityHash(), isolate);
- Handle<Object> result = SetHiddenProperty(object,
- isolate->factory()->identity_hash_string(), hash);
-
- if (result->IsUndefined()) {
- // Trying to get hash of detached proxy.
- return handle(Smi::FromInt(0), isolate);
- }
+ Handle<Object> hash(object->GetIdentityHash(), isolate);
+ if (hash->IsSmi()) return hash;
+ hash = handle(GenerateIdentityHash(isolate), isolate);
+ SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash);
return hash;
}
@@ -4816,21 +5146,16 @@ Object* JSProxy::GetIdentityHash() {
Handle<Object> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) {
- Isolate* isolate = proxy->GetIsolate();
-
- Handle<Object> hash(proxy->GetIdentityHash(), isolate);
- if (hash->IsSmi())
- return hash;
-
- hash = handle(proxy->GenerateIdentityHash(), isolate);
- proxy->set_hash(*hash);
- return hash;
+ return GetOrCreateIdentityHashHelper(proxy);
}
-Object* JSObject::GetHiddenProperty(Name* key) {
+Object* JSObject::GetHiddenProperty(Handle<Name> key) {
+ DisallowHeapAllocation no_gc;
ASSERT(key->IsUniqueName());
if (IsJSGlobalProxy()) {
+ // JSGlobalProxies store their hash internally.
+ ASSERT(*key != GetHeap()->identity_hash_string());
// For a proxy, use the prototype as target object.
Object* proxy_parent = GetPrototype();
// If the proxy is detached, return undefined.
@@ -4843,7 +5168,7 @@ Object* JSObject::GetHiddenProperty(Name* key) {
if (inline_value->IsSmi()) {
// Handle inline-stored identity hash.
- if (key == GetHeap()->identity_hash_string()) {
+ if (*key == GetHeap()->identity_hash_string()) {
return inline_value;
} else {
return GetHeap()->the_hole_value();
@@ -4865,6 +5190,8 @@ Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object,
ASSERT(key->IsUniqueName());
if (object->IsJSGlobalProxy()) {
+ // JSGlobalProxies store their hash internally.
+ ASSERT(*key != *isolate->factory()->identity_hash_string());
// For a proxy, use the prototype as target object.
Handle<Object> proxy_parent(object->GetPrototype(), isolate);
// If the proxy is detached, return undefined.
@@ -4953,13 +5280,16 @@ Object* JSObject::GetHiddenPropertiesHashTable() {
return GetHeap()->undefined_value();
}
} else {
- PropertyAttributes attributes;
- // You can't install a getter on a property indexed by the hidden string,
- // so we can be sure that GetLocalPropertyPostInterceptor returns a real
- // object.
- return GetLocalPropertyPostInterceptor(this,
- GetHeap()->hidden_string(),
- &attributes)->ToObjectUnchecked();
+ Isolate* isolate = GetIsolate();
+ LookupResult result(isolate);
+ LocalLookupRealNamedProperty(isolate->factory()->hidden_string(), &result);
+ if (result.IsFound()) {
+ ASSERT(result.IsNormal());
+ ASSERT(result.holder() == this);
+ Object* value = GetNormalizedProperty(&result);
+ if (!value->IsTheHole()) return value;
+ }
+ return GetHeap()->undefined_value();
}
}
@@ -4973,9 +5303,8 @@ Handle<ObjectHashTable> JSObject::GetOrCreateHiddenPropertiesHashtable(
return Handle<ObjectHashTable>::cast(inline_value);
}
- Handle<ObjectHashTable> hashtable = isolate->factory()->NewObjectHashTable(
- kInitialCapacity,
- USE_CUSTOM_MINIMUM_CAPACITY);
+ Handle<ObjectHashTable> hashtable = ObjectHashTable::New(
+ isolate, kInitialCapacity, USE_CUSTOM_MINIMUM_CAPACITY);
if (inline_value->IsSmi()) {
// We were storing the identity hash inline and now allocated an actual
@@ -4992,7 +5321,7 @@ Handle<ObjectHashTable> JSObject::GetOrCreateHiddenPropertiesHashtable(
DONT_ENUM,
OPTIMAL_REPRESENTATION,
ALLOW_AS_CONSTANT,
- OMIT_EXTENSIBILITY_CHECK);
+ OMIT_EXTENSIBILITY_CHECK).Assert();
return hashtable;
}
@@ -5017,9 +5346,7 @@ Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object,
int sorted_index = descriptors->GetSortedKeyIndex(0);
if (descriptors->GetKey(sorted_index) == isolate->heap()->hidden_string()
&& sorted_index < object->map()->NumberOfOwnDescriptors()) {
- ASSERT(descriptors->GetType(sorted_index) == FIELD);
- object->FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index),
- *value);
+ object->WriteToField(sorted_index, *value);
return object;
}
}
@@ -5031,7 +5358,7 @@ Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object,
DONT_ENUM,
OPTIMAL_REPRESENTATION,
ALLOW_AS_CONSTANT,
- OMIT_EXTENSIBILITY_CHECK);
+ OMIT_EXTENSIBILITY_CHECK).Assert();
return object;
}
@@ -5042,7 +5369,7 @@ Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object,
// Check local property, ignore interceptor.
Isolate* isolate = object->GetIsolate();
LookupResult result(isolate);
- object->LocalLookupRealNamedProperty(*name, &result);
+ object->LocalLookupRealNamedProperty(name, &result);
if (!result.IsFound()) return isolate->factory()->true_value();
// Normalize object if needed.
@@ -5052,8 +5379,8 @@ Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object,
}
-Handle<Object> JSObject::DeletePropertyWithInterceptor(Handle<JSObject> object,
- Handle<Name> name) {
+MaybeHandle<Object> JSObject::DeletePropertyWithInterceptor(
+ Handle<JSObject> object, Handle<Name> name) {
Isolate* isolate = object->GetIsolate();
// TODO(rossberg): Support symbols in the API.
@@ -5069,7 +5396,7 @@ Handle<Object> JSObject::DeletePropertyWithInterceptor(Handle<JSObject> object,
isolate, interceptor->data(), *object, *object);
v8::Handle<v8::Boolean> result =
args.Call(deleter, v8::Utils::ToLocal(Handle<String>::cast(name)));
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (!result.IsEmpty()) {
ASSERT(result->IsBoolean());
Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
@@ -5080,13 +5407,13 @@ Handle<Object> JSObject::DeletePropertyWithInterceptor(Handle<JSObject> object,
}
Handle<Object> result =
DeletePropertyPostInterceptor(object, name, NORMAL_DELETION);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return result;
}
-Handle<Object> JSObject::DeleteElementWithInterceptor(Handle<JSObject> object,
- uint32_t index) {
+MaybeHandle<Object> JSObject::DeleteElementWithInterceptor(
+ Handle<JSObject> object,
+ uint32_t index) {
Isolate* isolate = object->GetIsolate();
Factory* factory = isolate->factory();
@@ -5103,7 +5430,7 @@ Handle<Object> JSObject::DeleteElementWithInterceptor(Handle<JSObject> object,
PropertyCallbackArguments args(
isolate, interceptor->data(), *object, *object);
v8::Handle<v8::Boolean> result = args.Call(deleter, index);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (!result.IsEmpty()) {
ASSERT(result->IsBoolean());
Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
@@ -5111,24 +5438,23 @@ Handle<Object> JSObject::DeleteElementWithInterceptor(Handle<JSObject> object,
// Rebox CustomArguments::kReturnValueOffset before returning.
return handle(*result_internal, isolate);
}
- Handle<Object> delete_result = object->GetElementsAccessor()->Delete(
+ MaybeHandle<Object> delete_result = object->GetElementsAccessor()->Delete(
object, index, NORMAL_DELETION);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return delete_result;
}
-Handle<Object> JSObject::DeleteElement(Handle<JSObject> object,
- uint32_t index,
- DeleteMode mode) {
+MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object,
+ uint32_t index,
+ DeleteMode mode) {
Isolate* isolate = object->GetIsolate();
Factory* factory = isolate->factory();
// Check access rights if needed.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_DELETE)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_DELETE);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ !isolate->MayIndexedAccess(object, index, v8::ACCESS_DELETE)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return factory->false_value();
}
@@ -5158,21 +5484,24 @@ Handle<Object> JSObject::DeleteElement(Handle<JSObject> object,
if (object->map()->is_observed()) {
should_enqueue_change_record = HasLocalElement(object, index);
if (should_enqueue_change_record) {
- if (object->GetLocalElementAccessorPair(index) != NULL) {
+ if (!GetLocalElementAccessorPair(object, index).is_null()) {
old_value = Handle<Object>::cast(factory->the_hole_value());
} else {
- old_value = Object::GetElementNoExceptionThrown(isolate, object, index);
+ old_value = Object::GetElement(
+ isolate, object, index).ToHandleChecked();
}
}
}
// Skip interceptor if forcing deletion.
- Handle<Object> result;
+ MaybeHandle<Object> maybe_result;
if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) {
- result = DeleteElementWithInterceptor(object, index);
+ maybe_result = DeleteElementWithInterceptor(object, index);
} else {
- result = object->GetElementsAccessor()->Delete(object, index, mode);
+ maybe_result = object->GetElementsAccessor()->Delete(object, index, mode);
}
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object);
if (should_enqueue_change_record && !HasLocalElement(object, index)) {
Handle<String> name = factory->Uint32ToString(index);
@@ -5183,18 +5512,18 @@ Handle<Object> JSObject::DeleteElement(Handle<JSObject> object,
}
-Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
- Handle<Name> name,
- DeleteMode mode) {
+MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
+ Handle<Name> name,
+ DeleteMode mode) {
Isolate* isolate = object->GetIsolate();
// ECMA-262, 3rd, 8.6.2.5
ASSERT(name->IsName());
// Check access rights if needed.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_DELETE)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_DELETE);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ !isolate->MayNamedAccess(object, name, v8::ACCESS_DELETE)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->false_value();
}
@@ -5212,7 +5541,7 @@ Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
}
LookupResult lookup(isolate);
- object->LocalLookup(*name, &lookup, true);
+ object->LocalLookup(name, &lookup, true);
if (!lookup.IsFound()) return isolate->factory()->true_value();
// Ignore attributes if forcing a deletion.
if (lookup.IsDontDelete() && mode != FORCE_DELETION) {
@@ -5231,8 +5560,7 @@ Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
bool is_observed = object->map()->is_observed() &&
*name != isolate->heap()->hidden_string();
if (is_observed && lookup.IsDataProperty()) {
- old_value = Object::GetProperty(object, name);
- CHECK_NOT_EMPTY_HANDLE(isolate, old_value);
+ old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked();
}
Handle<Object> result;
@@ -5242,7 +5570,10 @@ Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
if (mode == FORCE_DELETION) {
result = DeletePropertyPostInterceptor(object, name, mode);
} else {
- result = DeletePropertyWithInterceptor(object, name);
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ DeletePropertyWithInterceptor(object, name),
+ Object);
}
} else {
// Normalize object if needed.
@@ -5259,9 +5590,9 @@ Handle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
}
-Handle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object,
- uint32_t index,
- DeleteMode mode) {
+MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object,
+ uint32_t index,
+ DeleteMode mode) {
if (object->IsJSProxy()) {
return JSProxy::DeleteElementWithHandler(
Handle<JSProxy>::cast(object), index, mode);
@@ -5270,9 +5601,9 @@ Handle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object,
}
-Handle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object,
- Handle<Name> name,
- DeleteMode mode) {
+MaybeHandle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object,
+ Handle<Name> name,
+ DeleteMode mode) {
if (object->IsJSProxy()) {
return JSProxy::DeletePropertyWithHandler(
Handle<JSProxy>::cast(object), name, mode);
@@ -5417,17 +5748,16 @@ bool JSObject::ReferencesObject(Object* obj) {
}
-Handle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
+MaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
Isolate* isolate = object->GetIsolate();
if (!object->map()->is_extensible()) return object;
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(object,
- isolate->factory()->undefined_value(),
- v8::ACCESS_KEYS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_KEYS);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ !isolate->MayNamedAccess(
+ object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->false_value();
}
@@ -5445,8 +5775,7 @@ Handle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
isolate->factory()->NewTypeError(
"cant_prevent_ext_external_array_elements",
HandleVector(&object, 1));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
// If there are fast elements we normalize.
@@ -5483,8 +5812,11 @@ static void FreezeDictionary(Dictionary* dictionary) {
PropertyDetails details = dictionary->DetailsAt(i);
int attrs = DONT_DELETE;
// READ_ONLY is an invalid attribute for JS setters/getters.
- if (details.type() != CALLBACKS ||
- !dictionary->ValueAt(i)->IsAccessorPair()) {
+ if (details.type() == CALLBACKS) {
+ Object* v = dictionary->ValueAt(i);
+ if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value();
+ if (!v->IsAccessorPair()) attrs |= READ_ONLY;
+ } else {
attrs |= READ_ONLY;
}
details = details.CopyAddAttributes(
@@ -5495,7 +5827,7 @@ static void FreezeDictionary(Dictionary* dictionary) {
}
-Handle<Object> JSObject::Freeze(Handle<JSObject> object) {
+MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) {
// Freezing sloppy arguments should be handled elsewhere.
ASSERT(!object->HasSloppyArgumentsElements());
ASSERT(!object->map()->is_observed());
@@ -5504,11 +5836,10 @@ Handle<Object> JSObject::Freeze(Handle<JSObject> object) {
Isolate* isolate = object->GetIsolate();
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(object,
- isolate->factory()->undefined_value(),
- v8::ACCESS_KEYS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_KEYS);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ !isolate->MayNamedAccess(
+ object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->false_value();
}
@@ -5526,8 +5857,7 @@ Handle<Object> JSObject::Freeze(Handle<JSObject> object) {
isolate->factory()->NewTypeError(
"cant_prevent_ext_external_array_elements",
HandleVector(&object, 1));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
Handle<SeededNumberDictionary> new_element_dictionary;
@@ -5539,8 +5869,7 @@ Handle<Object> JSObject::Freeze(Handle<JSObject> object) {
int capacity = 0;
int used = 0;
object->GetElementsCapacityAndUsage(&capacity, &used);
- new_element_dictionary =
- isolate->factory()->NewSeededNumberDictionary(used);
+ new_element_dictionary = SeededNumberDictionary::New(isolate, used);
// Move elements to a dictionary; avoid calling NormalizeElements to avoid
// unnecessary transitions.
@@ -5553,27 +5882,18 @@ Handle<Object> JSObject::Freeze(Handle<JSObject> object) {
}
}
- LookupResult result(isolate);
- Handle<Map> old_map(object->map());
- old_map->LookupTransition(*object, isolate->heap()->frozen_symbol(), &result);
- if (result.IsTransition()) {
- Handle<Map> transition_map(result.GetTransitionTarget());
+ Handle<Map> old_map(object->map(), isolate);
+ int transition_index = old_map->SearchTransition(
+ isolate->heap()->frozen_symbol());
+ if (transition_index != TransitionArray::kNotFound) {
+ Handle<Map> transition_map(old_map->GetTransition(transition_index));
ASSERT(transition_map->has_dictionary_elements());
ASSERT(transition_map->is_frozen());
ASSERT(!transition_map->is_extensible());
JSObject::MigrateToMap(object, transition_map);
} else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
// Create a new descriptor array with fully-frozen properties
- int num_descriptors = old_map->NumberOfOwnDescriptors();
- Handle<DescriptorArray> new_descriptors =
- DescriptorArray::CopyUpToAddAttributes(
- handle(old_map->instance_descriptors()), num_descriptors, FROZEN);
- Handle<Map> new_map = Map::CopyReplaceDescriptors(
- old_map, new_descriptors, INSERT_TRANSITION,
- isolate->factory()->frozen_symbol());
- new_map->freeze();
- new_map->set_is_extensible(false);
- new_map->set_elements_kind(DICTIONARY_ELEMENTS);
+ Handle<Map> new_map = Map::CopyForFreeze(old_map);
JSObject::MigrateToMap(object, new_map);
} else {
// Slow path: need to normalize properties for safety
@@ -5609,34 +5929,33 @@ Handle<Object> JSObject::Freeze(Handle<JSObject> object) {
void JSObject::SetObserved(Handle<JSObject> object) {
+ ASSERT(!object->IsJSGlobalProxy());
+ ASSERT(!object->IsJSGlobalObject());
Isolate* isolate = object->GetIsolate();
-
- if (object->map()->is_observed())
- return;
-
- LookupResult result(isolate);
- object->map()->LookupTransition(*object,
- isolate->heap()->observed_symbol(),
- &result);
-
Handle<Map> new_map;
- if (result.IsTransition()) {
- new_map = handle(result.GetTransitionTarget());
+ Handle<Map> old_map(object->map(), isolate);
+ ASSERT(!old_map->is_observed());
+ int transition_index = old_map->SearchTransition(
+ isolate->heap()->observed_symbol());
+ if (transition_index != TransitionArray::kNotFound) {
+ new_map = handle(old_map->GetTransition(transition_index), isolate);
ASSERT(new_map->is_observed());
- } else if (object->map()->CanHaveMoreTransitions()) {
- new_map = Map::CopyForObserved(handle(object->map()));
+ } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
+ new_map = Map::CopyForObserved(old_map);
} else {
- new_map = Map::Copy(handle(object->map()));
+ new_map = Map::Copy(old_map);
new_map->set_is_observed();
}
JSObject::MigrateToMap(object, new_map);
}
-Handle<JSObject> JSObject::Copy(Handle<JSObject> object) {
+Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object,
+ Representation representation,
+ int index) {
Isolate* isolate = object->GetIsolate();
- CALL_HEAP_FUNCTION(isolate,
- isolate->heap()->CopyJSObject(*object), JSObject);
+ Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate);
+ return Object::NewStorageFor(isolate, raw_value, representation);
}
@@ -5649,13 +5968,14 @@ class JSObjectWalkVisitor {
copying_(copying),
hints_(hints) {}
- Handle<JSObject> StructureWalk(Handle<JSObject> object);
+ MUST_USE_RESULT MaybeHandle<JSObject> StructureWalk(Handle<JSObject> object);
protected:
- inline Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object,
- Handle<JSObject> value) {
+ MUST_USE_RESULT inline MaybeHandle<JSObject> VisitElementOrProperty(
+ Handle<JSObject> object,
+ Handle<JSObject> value) {
Handle<AllocationSite> current_site = site_context()->EnterNewScope();
- Handle<JSObject> copy_of_value = StructureWalk(value);
+ MaybeHandle<JSObject> copy_of_value = StructureWalk(value);
site_context()->ExitScope(current_site, value);
return copy_of_value;
}
@@ -5673,7 +5993,7 @@ class JSObjectWalkVisitor {
template <class ContextObject>
-Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
+MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
Handle<JSObject> object) {
Isolate* isolate = this->isolate();
bool copying = this->copying();
@@ -5684,7 +6004,7 @@ Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
if (check.HasOverflowed()) {
isolate->StackOverflow();
- return Handle<JSObject>::null();
+ return MaybeHandle<JSObject>();
}
}
@@ -5698,14 +6018,8 @@ Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
if (site_context()->ShouldCreateMemento(object)) {
site_to_pass = site_context()->current();
}
- CALL_AND_RETRY_OR_DIE(isolate,
- isolate->heap()->CopyJSObject(*object,
- site_to_pass.is_null() ? NULL : *site_to_pass),
- { copy = Handle<JSObject>(JSObject::cast(__object__),
- isolate);
- break;
- },
- return Handle<JSObject>());
+ copy = isolate->factory()->CopyJSObjectWithAllocationSite(
+ object, site_to_pass);
} else {
copy = object;
}
@@ -5732,11 +6046,13 @@ Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
int index = descriptors->GetFieldIndex(i);
Handle<Object> value(object->RawFastPropertyAt(index), isolate);
if (value->IsJSObject()) {
- value = VisitElementOrProperty(copy, Handle<JSObject>::cast(value));
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>());
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, value,
+ VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
+ JSObject);
} else {
Representation representation = details.representation();
- value = NewStorageFor(isolate, value, representation);
+ value = Object::NewStorageFor(isolate, value, representation);
}
if (copying) {
copy->FastPropertyAtPut(index, *value);
@@ -5755,17 +6071,18 @@ Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
// In particular, don't try to copy the length attribute of
// an array.
if (attributes != NONE) continue;
- Handle<Object> value(
- copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(),
- isolate);
+ Handle<Object> value =
+ Object::GetProperty(copy, key_string).ToHandleChecked();
if (value->IsJSObject()) {
- Handle<JSObject> result = VisitElementOrProperty(
- copy, Handle<JSObject>::cast(value));
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
+ Handle<JSObject> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
+ JSObject);
if (copying) {
// Creating object copy for literals. No strict mode needed.
- CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty(
- copy, key_string, result, NONE, SLOPPY));
+ JSObject::SetProperty(
+ copy, key_string, result, NONE, SLOPPY).Assert();
}
}
}
@@ -5793,9 +6110,11 @@ Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
value->IsTheHole() ||
(IsFastObjectElementsKind(copy->GetElementsKind())));
if (value->IsJSObject()) {
- Handle<JSObject> result = VisitElementOrProperty(
- copy, Handle<JSObject>::cast(value));
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
+ Handle<JSObject> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
+ JSObject);
if (copying) {
elements->set(i, *result);
}
@@ -5813,9 +6132,11 @@ Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
if (element_dictionary->IsKey(k)) {
Handle<Object> value(element_dictionary->ValueAt(i), isolate);
if (value->IsJSObject()) {
- Handle<JSObject> result = VisitElementOrProperty(
- copy, Handle<JSObject>::cast(value));
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
+ Handle<JSObject> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
+ JSObject);
if (copying) {
element_dictionary->ValueAtPut(i, *result);
}
@@ -5847,27 +6168,65 @@ Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
}
-Handle<JSObject> JSObject::DeepWalk(
+MaybeHandle<JSObject> JSObject::DeepWalk(
Handle<JSObject> object,
AllocationSiteCreationContext* site_context) {
JSObjectWalkVisitor<AllocationSiteCreationContext> v(site_context, false,
kNoHints);
- Handle<JSObject> result = v.StructureWalk(object);
- ASSERT(result.is_null() || result.is_identical_to(object));
+ MaybeHandle<JSObject> result = v.StructureWalk(object);
+ Handle<JSObject> for_assert;
+ ASSERT(!result.ToHandle(&for_assert) || for_assert.is_identical_to(object));
return result;
}
-Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object,
- AllocationSiteUsageContext* site_context,
- DeepCopyHints hints) {
+MaybeHandle<JSObject> JSObject::DeepCopy(
+ Handle<JSObject> object,
+ AllocationSiteUsageContext* site_context,
+ DeepCopyHints hints) {
JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context, true, hints);
- Handle<JSObject> copy = v.StructureWalk(object);
- ASSERT(!copy.is_identical_to(object));
+ MaybeHandle<JSObject> copy = v.StructureWalk(object);
+ Handle<JSObject> for_assert;
+ ASSERT(!copy.ToHandle(&for_assert) || !for_assert.is_identical_to(object));
return copy;
}
+Handle<Object> JSObject::GetDataProperty(Handle<JSObject> object,
+ Handle<Name> key) {
+ Isolate* isolate = object->GetIsolate();
+ LookupResult lookup(isolate);
+ {
+ DisallowHeapAllocation no_allocation;
+ object->LookupRealNamedProperty(key, &lookup);
+ }
+ Handle<Object> result = isolate->factory()->undefined_value();
+ if (lookup.IsFound() && !lookup.IsTransition()) {
+ switch (lookup.type()) {
+ case NORMAL:
+ result = GetNormalizedProperty(
+ Handle<JSObject>(lookup.holder(), isolate), &lookup);
+ break;
+ case FIELD:
+ result = FastPropertyAt(Handle<JSObject>(lookup.holder(), isolate),
+ lookup.representation(),
+ lookup.GetFieldIndex().field_index());
+ break;
+ case CONSTANT:
+ result = Handle<Object>(lookup.GetConstant(), isolate);
+ break;
+ case CALLBACKS:
+ case HANDLER:
+ case INTERCEPTOR:
+ break;
+ case NONEXISTENT:
+ UNREACHABLE();
+ }
+ }
+ return result;
+}
+
+
// Tests for the fast common case for property enumeration:
// - This object and all prototypes has an enum cache (which means that
// it is no proxy, has no interceptors and needs no access checks).
@@ -5941,24 +6300,11 @@ int Map::NextFreePropertyIndex() {
}
-AccessorDescriptor* Map::FindAccessor(Name* name) {
- DescriptorArray* descs = instance_descriptors();
- int number_of_own_descriptors = NumberOfOwnDescriptors();
- for (int i = 0; i < number_of_own_descriptors; i++) {
- if (descs->GetType(i) == CALLBACKS && name->Equals(descs->GetKey(i))) {
- return descs->GetCallbacks(i);
- }
- }
- return NULL;
-}
-
-
void JSReceiver::LocalLookup(
- Name* name, LookupResult* result, bool search_hidden_prototypes) {
+ Handle<Name> name, LookupResult* result, bool search_hidden_prototypes) {
+ DisallowHeapAllocation no_gc;
ASSERT(name->IsName());
- Heap* heap = GetHeap();
-
if (IsJSGlobalProxy()) {
Object* proto = GetPrototype();
if (proto->IsNull()) return result->NotFound();
@@ -5982,7 +6328,7 @@ void JSReceiver::LocalLookup(
// Check for lookup interceptor except when bootstrapping.
if (js_object->HasNamedInterceptor() &&
- !heap->isolate()->bootstrapper()->IsActive()) {
+ !GetIsolate()->bootstrapper()->IsActive()) {
result->InterceptorResult(js_object);
return;
}
@@ -5999,11 +6345,12 @@ void JSReceiver::LocalLookup(
}
-void JSReceiver::Lookup(Name* name, LookupResult* result) {
+void JSReceiver::Lookup(Handle<Name> name, LookupResult* result) {
+ DisallowHeapAllocation no_gc;
// Ecma-262 3rd 8.6.2.4
- Heap* heap = GetHeap();
+ Handle<Object> null_value = GetIsolate()->factory()->null_value();
for (Object* current = this;
- current != heap->null_value();
+ current != *null_value;
current = JSObject::cast(current)->GetPrototype()) {
JSReceiver::cast(current)->LocalLookup(name, result, false);
if (result->IsFound()) return;
@@ -6013,10 +6360,11 @@ void JSReceiver::Lookup(Name* name, LookupResult* result) {
// Search object and its prototype chain for callback properties.
-void JSObject::LookupCallbackProperty(Name* name, LookupResult* result) {
- Heap* heap = GetHeap();
+void JSObject::LookupCallbackProperty(Handle<Name> name, LookupResult* result) {
+ DisallowHeapAllocation no_gc;
+ Handle<Object> null_value = GetIsolate()->factory()->null_value();
for (Object* current = this;
- current != heap->null_value() && current->IsJSObject();
+ current != *null_value && current->IsJSObject();
current = JSObject::cast(current)->GetPrototype()) {
JSObject::cast(current)->LocalLookupRealNamedProperty(name, result);
if (result->IsPropertyCallbacks()) return;
@@ -6025,6 +6373,247 @@ void JSObject::LookupCallbackProperty(Name* name, LookupResult* result) {
}
+static bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
+ int len = array->length();
+ for (int i = 0; i < len; i++) {
+ Object* e = array->get(i);
+ if (!(e->IsString() || e->IsNumber())) return false;
+ }
+ return true;
+}
+
+
+static Handle<FixedArray> ReduceFixedArrayTo(
+ Handle<FixedArray> array, int length) {
+ ASSERT(array->length() >= length);
+ if (array->length() == length) return array;
+
+ Handle<FixedArray> new_array =
+ array->GetIsolate()->factory()->NewFixedArray(length);
+ for (int i = 0; i < length; ++i) new_array->set(i, array->get(i));
+ return new_array;
+}
+
+
+static Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object,
+ bool cache_result) {
+ Isolate* isolate = object->GetIsolate();
+ if (object->HasFastProperties()) {
+ int own_property_count = object->map()->EnumLength();
+ // If the enum length of the given map is set to kInvalidEnumCache, this
+ // means that the map itself has never used the present enum cache. The
+ // first step to using the cache is to set the enum length of the map by
+ // counting the number of own descriptors that are not DONT_ENUM or
+ // SYMBOLIC.
+ if (own_property_count == kInvalidEnumCacheSentinel) {
+ own_property_count = object->map()->NumberOfDescribedProperties(
+ OWN_DESCRIPTORS, DONT_SHOW);
+ } else {
+ ASSERT(own_property_count == object->map()->NumberOfDescribedProperties(
+ OWN_DESCRIPTORS, DONT_SHOW));
+ }
+
+ if (object->map()->instance_descriptors()->HasEnumCache()) {
+ DescriptorArray* desc = object->map()->instance_descriptors();
+ Handle<FixedArray> keys(desc->GetEnumCache(), isolate);
+
+ // In case the number of properties required in the enum are actually
+ // present, we can reuse the enum cache. Otherwise, this means that the
+ // enum cache was generated for a previous (smaller) version of the
+ // Descriptor Array. In that case we regenerate the enum cache.
+ if (own_property_count <= keys->length()) {
+ if (cache_result) object->map()->SetEnumLength(own_property_count);
+ isolate->counters()->enum_cache_hits()->Increment();
+ return ReduceFixedArrayTo(keys, own_property_count);
+ }
+ }
+
+ Handle<Map> map(object->map());
+
+ if (map->instance_descriptors()->IsEmpty()) {
+ isolate->counters()->enum_cache_hits()->Increment();
+ if (cache_result) map->SetEnumLength(0);
+ return isolate->factory()->empty_fixed_array();
+ }
+
+ isolate->counters()->enum_cache_misses()->Increment();
+
+ Handle<FixedArray> storage = isolate->factory()->NewFixedArray(
+ own_property_count);
+ Handle<FixedArray> indices = isolate->factory()->NewFixedArray(
+ own_property_count);
+
+ Handle<DescriptorArray> descs =
+ Handle<DescriptorArray>(object->map()->instance_descriptors(), isolate);
+
+ int size = map->NumberOfOwnDescriptors();
+ int index = 0;
+
+ for (int i = 0; i < size; i++) {
+ PropertyDetails details = descs->GetDetails(i);
+ Object* key = descs->GetKey(i);
+ if (!(details.IsDontEnum() || key->IsSymbol())) {
+ storage->set(index, key);
+ if (!indices.is_null()) {
+ if (details.type() != FIELD) {
+ indices = Handle<FixedArray>();
+ } else {
+ int field_index = descs->GetFieldIndex(i);
+ if (field_index >= map->inobject_properties()) {
+ field_index = -(field_index - map->inobject_properties() + 1);
+ }
+ field_index = field_index << 1;
+ if (details.representation().IsDouble()) {
+ field_index |= 1;
+ }
+ indices->set(index, Smi::FromInt(field_index));
+ }
+ }
+ index++;
+ }
+ }
+ ASSERT(index == storage->length());
+
+ Handle<FixedArray> bridge_storage =
+ isolate->factory()->NewFixedArray(
+ DescriptorArray::kEnumCacheBridgeLength);
+ DescriptorArray* desc = object->map()->instance_descriptors();
+ desc->SetEnumCache(*bridge_storage,
+ *storage,
+ indices.is_null() ? Object::cast(Smi::FromInt(0))
+ : Object::cast(*indices));
+ if (cache_result) {
+ object->map()->SetEnumLength(own_property_count);
+ }
+ return storage;
+ } else {
+ Handle<NameDictionary> dictionary(object->property_dictionary());
+ int length = dictionary->NumberOfEnumElements();
+ if (length == 0) {
+ return Handle<FixedArray>(isolate->heap()->empty_fixed_array());
+ }
+ Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length);
+ dictionary->CopyEnumKeysTo(*storage);
+ return storage;
+ }
+}
+
+
+MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
+ KeyCollectionType type) {
+ USE(ContainsOnlyValidKeys);
+ Isolate* isolate = object->GetIsolate();
+ Handle<FixedArray> content = isolate->factory()->empty_fixed_array();
+ Handle<JSObject> arguments_boilerplate = Handle<JSObject>(
+ isolate->context()->native_context()->sloppy_arguments_boilerplate(),
+ isolate);
+ Handle<JSFunction> arguments_function = Handle<JSFunction>(
+ JSFunction::cast(arguments_boilerplate->map()->constructor()),
+ isolate);
+
+ // Only collect keys if access is permitted.
+ for (Handle<Object> p = object;
+ *p != isolate->heap()->null_value();
+ p = Handle<Object>(p->GetPrototype(isolate), isolate)) {
+ if (p->IsJSProxy()) {
+ Handle<JSProxy> proxy(JSProxy::cast(*p), isolate);
+ Handle<Object> args[] = { proxy };
+ Handle<Object> names;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, names,
+ Execution::Call(isolate,
+ isolate->proxy_enumerate(),
+ object,
+ ARRAY_SIZE(args),
+ args),
+ FixedArray);
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, content,
+ FixedArray::AddKeysFromArrayLike(
+ content, Handle<JSObject>::cast(names)),
+ FixedArray);
+ break;
+ }
+
+ Handle<JSObject> current(JSObject::cast(*p), isolate);
+
+ // Check access rights if required.
+ if (current->IsAccessCheckNeeded() &&
+ !isolate->MayNamedAccess(
+ current, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
+ isolate->ReportFailedAccessCheck(current, v8::ACCESS_KEYS);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray);
+ break;
+ }
+
+ // Compute the element keys.
+ Handle<FixedArray> element_keys =
+ isolate->factory()->NewFixedArray(current->NumberOfEnumElements());
+ current->GetEnumElementKeys(*element_keys);
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, content,
+ FixedArray::UnionOfKeys(content, element_keys),
+ FixedArray);
+ ASSERT(ContainsOnlyValidKeys(content));
+
+ // Add the element keys from the interceptor.
+ if (current->HasIndexedInterceptor()) {
+ Handle<JSObject> result;
+ if (JSObject::GetKeysForIndexedInterceptor(
+ current, object).ToHandle(&result)) {
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, content,
+ FixedArray::AddKeysFromArrayLike(content, result),
+ FixedArray);
+ }
+ ASSERT(ContainsOnlyValidKeys(content));
+ }
+
+ // We can cache the computed property keys if access checks are
+ // not needed and no interceptors are involved.
+ //
+ // We do not use the cache if the object has elements and
+ // therefore it does not make sense to cache the property names
+ // for arguments objects. Arguments objects will always have
+ // elements.
+ // Wrapped strings have elements, but don't have an elements
+ // array or dictionary. So the fast inline test for whether to
+ // use the cache says yes, so we should not create a cache.
+ bool cache_enum_keys =
+ ((current->map()->constructor() != *arguments_function) &&
+ !current->IsJSValue() &&
+ !current->IsAccessCheckNeeded() &&
+ !current->HasNamedInterceptor() &&
+ !current->HasIndexedInterceptor());
+ // Compute the property keys and cache them if possible.
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, content,
+ FixedArray::UnionOfKeys(
+ content, GetEnumPropertyKeys(current, cache_enum_keys)),
+ FixedArray);
+ ASSERT(ContainsOnlyValidKeys(content));
+
+ // Add the property keys from the interceptor.
+ if (current->HasNamedInterceptor()) {
+ Handle<JSObject> result;
+ if (JSObject::GetKeysForNamedInterceptor(
+ current, object).ToHandle(&result)) {
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, content,
+ FixedArray::AddKeysFromArrayLike(content, result),
+ FixedArray);
+ }
+ ASSERT(ContainsOnlyValidKeys(content));
+ }
+
+ // If we only want local properties we bail out after the first
+ // iteration.
+ if (type == LOCAL_ONLY) break;
+ }
+ return content;
+}
+
+
// Try to update an accessor in an elements dictionary. Return true if the
// update succeeded, and false otherwise.
static bool UpdateGetterSetterInDictionary(
@@ -6124,7 +6713,7 @@ Handle<AccessorPair> JSObject::CreateAccessorPairFor(Handle<JSObject> object,
Handle<Name> name) {
Isolate* isolate = object->GetIsolate();
LookupResult result(isolate);
- object->LocalLookupRealNamedProperty(*name, &result);
+ object->LocalLookupRealNamedProperty(name, &result);
if (result.IsPropertyCallbacks()) {
// Note that the result can actually have IsDontDelete() == true when we
// e.g. have to fall back to the slow case while adding a setter after
@@ -6171,7 +6760,7 @@ void JSObject::DefinePropertyAccessor(Handle<JSObject> object,
bool JSObject::CanSetCallback(Handle<JSObject> object, Handle<Name> name) {
Isolate* isolate = object->GetIsolate();
ASSERT(!object->IsAccessCheckNeeded() ||
- isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET));
+ isolate->MayNamedAccess(object, name, v8::ACCESS_SET));
// Check if there is an API defined callback object which prohibits
// callback overwriting in this object or its prototype chain.
@@ -6180,7 +6769,7 @@ bool JSObject::CanSetCallback(Handle<JSObject> object, Handle<Name> name) {
// to be overwritten because allowing overwriting could potentially
// cause security problems.
LookupResult callback_result(isolate);
- object->LookupCallbackProperty(*name, &callback_result);
+ object->LookupCallbackProperty(name, &callback_result);
if (callback_result.IsFound()) {
Object* callback_obj = callback_result.GetCallbackObject();
if (callback_obj->IsAccessorInfo()) {
@@ -6294,8 +6883,9 @@ void JSObject::DefineAccessor(Handle<JSObject> object,
Isolate* isolate = object->GetIsolate();
// Check access rights if needed.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
+ !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
+ // TODO(yangguo): Issue 3269, check for scheduled exception missing?
return;
}
@@ -6317,7 +6907,7 @@ void JSObject::DefineAccessor(Handle<JSObject> object,
AssertNoContextChange ncc(isolate);
// Try to flatten before operating on the string.
- if (name->IsString()) String::cast(*name)->TryFlatten();
+ if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
if (!JSObject::CanSetCallback(object, name)) return;
@@ -6331,16 +6921,17 @@ void JSObject::DefineAccessor(Handle<JSObject> object,
if (is_observed) {
if (is_element) {
preexists = HasLocalElement(object, index);
- if (preexists && object->GetLocalElementAccessorPair(index) == NULL) {
- old_value = Object::GetElementNoExceptionThrown(isolate, object, index);
+ if (preexists && GetLocalElementAccessorPair(object, index).is_null()) {
+ old_value =
+ Object::GetElement(isolate, object, index).ToHandleChecked();
}
} else {
LookupResult lookup(isolate);
- object->LocalLookup(*name, &lookup, true);
+ object->LocalLookup(name, &lookup, true);
preexists = lookup.IsProperty();
if (preexists && lookup.IsDataProperty()) {
- old_value = Object::GetProperty(object, name);
- CHECK_NOT_EMPTY_HANDLE(isolate, old_value);
+ old_value =
+ Object::GetPropertyOrElement(object, name).ToHandleChecked();
}
}
}
@@ -6389,25 +6980,6 @@ static bool TryAccessorTransition(Handle<JSObject> self,
}
-static MaybeObject* CopyInsertDescriptor(Map* map,
- Name* name,
- AccessorPair* accessors,
- PropertyAttributes attributes) {
- CallbacksDescriptor new_accessors_desc(name, accessors, attributes);
- return map->CopyInsertDescriptor(&new_accessors_desc, INSERT_TRANSITION);
-}
-
-
-static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
- Handle<Name> name,
- Handle<AccessorPair> accessors,
- PropertyAttributes attributes) {
- CALL_HEAP_FUNCTION(map->GetIsolate(),
- CopyInsertDescriptor(*map, *name, *accessors, attributes),
- Map);
-}
-
-
bool JSObject::DefineFastAccessor(Handle<JSObject> object,
Handle<Name> name,
AccessorComponent component,
@@ -6416,7 +6988,7 @@ bool JSObject::DefineFastAccessor(Handle<JSObject> object,
ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined());
Isolate* isolate = object->GetIsolate();
LookupResult result(isolate);
- object->LocalLookup(*name, &result);
+ object->LocalLookup(name, &result);
if (result.IsFound() && !result.IsPropertyCallbacks()) {
return false;
@@ -6458,8 +7030,8 @@ bool JSObject::DefineFastAccessor(Handle<JSObject> object,
if (result.IsFound()) {
Handle<Map> target(result.GetTransitionTarget());
int descriptor_number = target->LastAdded();
- ASSERT(target->instance_descriptors()->GetKey(descriptor_number)
- ->Equals(*name));
+ ASSERT(Name::Equals(name,
+ handle(target->instance_descriptors()->GetKey(descriptor_number))));
return TryAccessorTransition(object, target, descriptor_number,
component, accessor, attributes);
}
@@ -6472,24 +7044,27 @@ bool JSObject::DefineFastAccessor(Handle<JSObject> object,
? AccessorPair::Copy(Handle<AccessorPair>(source_accessors))
: isolate->factory()->NewAccessorPair();
accessors->set(component, *accessor);
- Handle<Map> new_map = CopyInsertDescriptor(Handle<Map>(object->map()),
- name, accessors, attributes);
+
+ CallbacksDescriptor new_accessors_desc(name, accessors, attributes);
+ Handle<Map> new_map = Map::CopyInsertDescriptor(
+ handle(object->map()), &new_accessors_desc, INSERT_TRANSITION);
+
JSObject::MigrateToMap(object, new_map);
return true;
}
-Handle<Object> JSObject::SetAccessor(Handle<JSObject> object,
- Handle<AccessorInfo> info) {
+MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
+ Handle<AccessorInfo> info) {
Isolate* isolate = object->GetIsolate();
Factory* factory = isolate->factory();
Handle<Name> name(Name::cast(info->name()));
// Check access rights if needed.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_SET)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return factory->undefined_value();
}
@@ -6505,7 +7080,7 @@ Handle<Object> JSObject::SetAccessor(Handle<JSObject> object,
AssertNoContextChange ncc(isolate);
// Try to flatten before operating on the string.
- if (name->IsString()) FlattenString(Handle<String>::cast(name));
+ if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
if (!JSObject::CanSetCallback(object, name)) {
return factory->undefined_value();
@@ -6548,7 +7123,7 @@ Handle<Object> JSObject::SetAccessor(Handle<JSObject> object,
} else {
// Lookup the name.
LookupResult result(isolate);
- object->LocalLookup(*name, &result, true);
+ object->LocalLookup(name, &result, true);
// ES5 forbids turning a property into an accessor if it's not
// configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5).
if (result.IsFound() && (result.IsReadOnly() || result.IsDontDelete())) {
@@ -6562,9 +7137,9 @@ Handle<Object> JSObject::SetAccessor(Handle<JSObject> object,
}
-Handle<Object> JSObject::GetAccessor(Handle<JSObject> object,
- Handle<Name> name,
- AccessorComponent component) {
+MaybeHandle<Object> JSObject::GetAccessor(Handle<JSObject> object,
+ Handle<Name> name,
+ AccessorComponent component) {
Isolate* isolate = object->GetIsolate();
// Make sure that the top context does not change when doing callbacks or
@@ -6573,9 +7148,9 @@ Handle<Object> JSObject::GetAccessor(Handle<JSObject> object,
// Check access rights if needed.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(object, name, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ !isolate->MayNamedAccess(object, name, v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
}
@@ -6604,7 +7179,7 @@ Handle<Object> JSObject::GetAccessor(Handle<JSObject> object,
!obj->IsNull();
obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) {
LookupResult result(isolate);
- JSReceiver::cast(*obj)->LocalLookup(*name, &result);
+ JSReceiver::cast(*obj)->LocalLookup(name, &result);
if (result.IsFound()) {
if (result.IsReadOnly()) return isolate->factory()->undefined_value();
if (result.IsPropertyCallbacks()) {
@@ -6649,31 +7224,20 @@ Object* JSObject::SlowReverseLookup(Object* value) {
}
-Handle<Map> Map::RawCopy(Handle<Map> map,
- int instance_size) {
- CALL_HEAP_FUNCTION(map->GetIsolate(),
- map->RawCopy(instance_size),
- Map);
-}
-
-
-MaybeObject* Map::RawCopy(int instance_size) {
- Map* result;
- MaybeObject* maybe_result =
- GetHeap()->AllocateMap(instance_type(), instance_size);
- if (!maybe_result->To(&result)) return maybe_result;
-
- result->set_prototype(prototype());
- result->set_constructor(constructor());
- result->set_bit_field(bit_field());
- result->set_bit_field2(bit_field2());
- int new_bit_field3 = bit_field3();
+Handle<Map> Map::RawCopy(Handle<Map> map, int instance_size) {
+ Handle<Map> result = map->GetIsolate()->factory()->NewMap(
+ map->instance_type(), instance_size);
+ result->set_prototype(map->prototype());
+ result->set_constructor(map->constructor());
+ result->set_bit_field(map->bit_field());
+ result->set_bit_field2(map->bit_field2());
+ int new_bit_field3 = map->bit_field3();
new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true);
new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0);
new_bit_field3 = EnumLengthBits::update(new_bit_field3,
kInvalidEnumCacheSentinel);
new_bit_field3 = Deprecated::update(new_bit_field3, false);
- if (!is_dictionary_map()) {
+ if (!map->is_dictionary_map()) {
new_bit_field3 = IsUnstable::update(new_bit_field3, false);
}
result->set_bit_field3(new_bit_field3);
@@ -6681,6 +7245,50 @@ MaybeObject* Map::RawCopy(int instance_size) {
}
+Handle<Map> Map::Normalize(Handle<Map> fast_map,
+ PropertyNormalizationMode mode) {
+ ASSERT(!fast_map->is_dictionary_map());
+
+ Isolate* isolate = fast_map->GetIsolate();
+ Handle<NormalizedMapCache> cache(
+ isolate->context()->native_context()->normalized_map_cache());
+
+ Handle<Map> new_map;
+ if (cache->Get(fast_map, mode).ToHandle(&new_map)) {
+#ifdef VERIFY_HEAP
+ if (FLAG_verify_heap) {
+ new_map->SharedMapVerify();
+ }
+#endif
+#ifdef ENABLE_SLOW_ASSERTS
+ if (FLAG_enable_slow_asserts) {
+ // The cached map should match newly created normalized map bit-by-bit,
+ // except for the code cache, which can contain some ics which can be
+ // applied to the shared map.
+ Handle<Map> fresh = Map::CopyNormalized(
+ fast_map, mode, SHARED_NORMALIZED_MAP);
+
+ ASSERT(memcmp(fresh->address(),
+ new_map->address(),
+ Map::kCodeCacheOffset) == 0);
+ STATIC_ASSERT(Map::kDependentCodeOffset ==
+ Map::kCodeCacheOffset + kPointerSize);
+ int offset = Map::kDependentCodeOffset + kPointerSize;
+ ASSERT(memcmp(fresh->address() + offset,
+ new_map->address() + offset,
+ Map::kSize - offset) == 0);
+ }
+#endif
+ } else {
+ new_map = Map::CopyNormalized(fast_map, mode, SHARED_NORMALIZED_MAP);
+ cache->Set(fast_map, new_map);
+ isolate->counters()->normalized_maps()->Increment();
+ }
+ fast_map->NotifyLeafMapLayoutChange();
+ return new_map;
+}
+
+
Handle<Map> Map::CopyNormalized(Handle<Map> map,
PropertyNormalizationMode mode,
NormalizedMapSharingMode sharing) {
@@ -6689,7 +7297,7 @@ Handle<Map> Map::CopyNormalized(Handle<Map> map,
new_instance_size -= map->inobject_properties() * kPointerSize;
}
- Handle<Map> result = Map::RawCopy(map, new_instance_size);
+ Handle<Map> result = RawCopy(map, new_instance_size);
if (mode != CLEAR_INOBJECT_PROPERTIES) {
result->set_inobject_properties(map->inobject_properties());
@@ -6710,99 +7318,57 @@ Handle<Map> Map::CopyNormalized(Handle<Map> map,
Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) {
- CALL_HEAP_FUNCTION(map->GetIsolate(), map->CopyDropDescriptors(), Map);
-}
-
-
-MaybeObject* Map::CopyDropDescriptors() {
- Map* result;
- MaybeObject* maybe_result = RawCopy(instance_size());
- if (!maybe_result->To(&result)) return maybe_result;
+ Handle<Map> result = RawCopy(map, map->instance_size());
// Please note instance_type and instance_size are set when allocated.
- result->set_inobject_properties(inobject_properties());
- result->set_unused_property_fields(unused_property_fields());
+ result->set_inobject_properties(map->inobject_properties());
+ result->set_unused_property_fields(map->unused_property_fields());
- result->set_pre_allocated_property_fields(pre_allocated_property_fields());
+ result->set_pre_allocated_property_fields(
+ map->pre_allocated_property_fields());
result->set_is_shared(false);
- result->ClearCodeCache(GetHeap());
- NotifyLeafMapLayoutChange();
+ result->ClearCodeCache(map->GetHeap());
+ map->NotifyLeafMapLayoutChange();
return result;
}
-MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors,
- Descriptor* descriptor) {
+Handle<Map> Map::ShareDescriptor(Handle<Map> map,
+ Handle<DescriptorArray> descriptors,
+ Descriptor* descriptor) {
// Sanity check. This path is only to be taken if the map owns its descriptor
// array, implying that its NumberOfOwnDescriptors equals the number of
// descriptors in the descriptor array.
- ASSERT(NumberOfOwnDescriptors() ==
- instance_descriptors()->number_of_descriptors());
- Map* result;
- MaybeObject* maybe_result = CopyDropDescriptors();
- if (!maybe_result->To(&result)) return maybe_result;
+ ASSERT(map->NumberOfOwnDescriptors() ==
+ map->instance_descriptors()->number_of_descriptors());
- Name* name = descriptor->GetKey();
-
- TransitionArray* transitions;
- MaybeObject* maybe_transitions =
- AddTransition(name, result, SIMPLE_TRANSITION);
- if (!maybe_transitions->To(&transitions)) return maybe_transitions;
-
- int old_size = descriptors->number_of_descriptors();
-
- DescriptorArray* new_descriptors;
-
- if (descriptors->NumberOfSlackDescriptors() > 0) {
- new_descriptors = descriptors;
- new_descriptors->Append(descriptor);
- } else {
- // Descriptor arrays grow by 50%.
- MaybeObject* maybe_descriptors = DescriptorArray::Allocate(
- GetIsolate(), old_size, old_size < 4 ? 1 : old_size / 2);
- if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
-
- DescriptorArray::WhitenessWitness witness(new_descriptors);
+ Handle<Map> result = CopyDropDescriptors(map);
+ Handle<Name> name = descriptor->GetKey();
+ Handle<TransitionArray> transitions =
+ TransitionArray::CopyInsert(map, name, result, SIMPLE_TRANSITION);
- // Copy the descriptors, inserting a descriptor.
- for (int i = 0; i < old_size; ++i) {
- new_descriptors->CopyFrom(i, descriptors, i, witness);
+ // Ensure there's space for the new descriptor in the shared descriptor array.
+ if (descriptors->NumberOfSlackDescriptors() == 0) {
+ int old_size = descriptors->number_of_descriptors();
+ if (old_size == 0) {
+ descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1);
+ } else {
+ EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2);
+ descriptors = handle(map->instance_descriptors());
}
+ }
- new_descriptors->Append(descriptor, witness);
-
- if (old_size > 0) {
- // If the source descriptors had an enum cache we copy it. This ensures
- // that the maps to which we push the new descriptor array back can rely
- // on a cache always being available once it is set. If the map has more
- // enumerated descriptors than available in the original cache, the cache
- // will be lazily replaced by the extended cache when needed.
- if (descriptors->HasEnumCache()) {
- new_descriptors->CopyEnumCacheFrom(descriptors);
- }
-
- Map* map;
- // Replace descriptors by new_descriptors in all maps that share it.
-
- GetHeap()->incremental_marking()->RecordWrites(descriptors);
- for (Object* current = GetBackPointer();
- !current->IsUndefined();
- current = map->GetBackPointer()) {
- map = Map::cast(current);
- if (map->instance_descriptors() != descriptors) break;
- map->set_instance_descriptors(new_descriptors);
- }
+ // Commit the state atomically.
+ DisallowHeapAllocation no_gc;
- set_instance_descriptors(new_descriptors);
- }
- }
+ descriptors->Append(descriptor);
+ result->SetBackPointer(*map);
+ result->InitializeDescriptors(*descriptors);
- result->SetBackPointer(this);
- result->InitializeDescriptors(new_descriptors);
- ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1);
+ ASSERT(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
- set_transitions(transitions);
- set_owns_descriptors(false);
+ map->set_transitions(*transitions);
+ map->set_owns_descriptors(false);
return result;
}
@@ -6811,33 +7377,28 @@ MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors,
Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map,
Handle<DescriptorArray> descriptors,
TransitionFlag flag,
- Handle<Name> name) {
- CALL_HEAP_FUNCTION(map->GetIsolate(),
- map->CopyReplaceDescriptors(*descriptors, flag, *name),
- Map);
-}
-
-
-MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
- TransitionFlag flag,
- Name* name,
- SimpleTransitionFlag simple_flag) {
+ MaybeHandle<Name> maybe_name,
+ SimpleTransitionFlag simple_flag) {
ASSERT(descriptors->IsSortedNoDuplicates());
- Map* result;
- MaybeObject* maybe_result = CopyDropDescriptors();
- if (!maybe_result->To(&result)) return maybe_result;
-
- result->InitializeDescriptors(descriptors);
+ Handle<Map> result = CopyDropDescriptors(map);
+ result->InitializeDescriptors(*descriptors);
- if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) {
- TransitionArray* transitions;
- MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag);
- if (!maybe_transitions->To(&transitions)) return maybe_transitions;
- set_transitions(transitions);
- result->SetBackPointer(this);
+ if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) {
+ Handle<Name> name;
+ CHECK(maybe_name.ToHandle(&name));
+ Handle<TransitionArray> transitions = TransitionArray::CopyInsert(
+ map, name, result, simple_flag);
+ map->set_transitions(*transitions);
+ result->SetBackPointer(*map);
} else {
- descriptors->InitializeRepresentations(Representation::Tagged());
+ int length = descriptors->number_of_descriptors();
+ for (int i = 0; i < length; i++) {
+ descriptors->SetRepresentation(i, Representation::Tagged());
+ if (descriptors->GetDetails(i).type() == FIELD) {
+ descriptors->SetValue(i, HeapType::Any());
+ }
+ }
}
return result;
@@ -6851,7 +7412,7 @@ Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
Handle<DescriptorArray> descriptors) {
ASSERT(descriptors->IsSortedNoDuplicates());
- Handle<Map> result = Map::CopyDropDescriptors(map);
+ Handle<Map> result = CopyDropDescriptors(map);
result->InitializeDescriptors(*descriptors);
result->SetNumberOfOwnDescriptors(new_descriptor + 1);
@@ -6868,8 +7429,8 @@ Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
result->set_owns_descriptors(false);
Handle<Name> name = handle(descriptors->GetKey(new_descriptor));
- Handle<TransitionArray> transitions = Map::AddTransition(map, name, result,
- SIMPLE_TRANSITION);
+ Handle<TransitionArray> transitions = TransitionArray::CopyInsert(
+ map, name, result, SIMPLE_TRANSITION);
map->set_transitions(*transitions);
result->SetBackPointer(*map);
@@ -6878,52 +7439,48 @@ Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
}
-MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) {
+Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
+ TransitionFlag flag) {
if (flag == INSERT_TRANSITION) {
- ASSERT(!HasElementsTransition() ||
- ((elements_transition_map()->elements_kind() == DICTIONARY_ELEMENTS ||
+ ASSERT(!map->HasElementsTransition() ||
+ ((map->elements_transition_map()->elements_kind() ==
+ DICTIONARY_ELEMENTS ||
IsExternalArrayElementsKind(
- elements_transition_map()->elements_kind())) &&
+ map->elements_transition_map()->elements_kind())) &&
(kind == DICTIONARY_ELEMENTS ||
IsExternalArrayElementsKind(kind))));
ASSERT(!IsFastElementsKind(kind) ||
- IsMoreGeneralElementsKindTransition(elements_kind(), kind));
- ASSERT(kind != elements_kind());
+ IsMoreGeneralElementsKindTransition(map->elements_kind(), kind));
+ ASSERT(kind != map->elements_kind());
}
bool insert_transition =
- flag == INSERT_TRANSITION && !HasElementsTransition();
+ flag == INSERT_TRANSITION && !map->HasElementsTransition();
- if (insert_transition && owns_descriptors()) {
+ if (insert_transition && map->owns_descriptors()) {
// In case the map owned its own descriptors, share the descriptors and
// transfer ownership to the new map.
- Map* new_map;
- MaybeObject* maybe_new_map = CopyDropDescriptors();
- if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+ Handle<Map> new_map = CopyDropDescriptors(map);
- MaybeObject* added_elements = set_elements_transition_map(new_map);
- if (added_elements->IsFailure()) return added_elements;
+ SetElementsTransitionMap(map, new_map);
new_map->set_elements_kind(kind);
- new_map->InitializeDescriptors(instance_descriptors());
- new_map->SetBackPointer(this);
- set_owns_descriptors(false);
+ new_map->InitializeDescriptors(map->instance_descriptors());
+ new_map->SetBackPointer(*map);
+ map->set_owns_descriptors(false);
return new_map;
}
// In case the map did not own its own descriptors, a split is forced by
// copying the map; creating a new descriptor array cell.
// Create a new free-floating map only if we are not allowed to store it.
- Map* new_map;
- MaybeObject* maybe_new_map = Copy();
- if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+ Handle<Map> new_map = Copy(map);
new_map->set_elements_kind(kind);
if (insert_transition) {
- MaybeObject* added_elements = set_elements_transition_map(new_map);
- if (added_elements->IsFailure()) return added_elements;
- new_map->SetBackPointer(this);
+ SetElementsTransitionMap(map, new_map);
+ new_map->SetBackPointer(*map);
}
return new_map;
@@ -6939,14 +7496,13 @@ Handle<Map> Map::CopyForObserved(Handle<Map> map) {
// transfer ownership to the new map.
Handle<Map> new_map;
if (map->owns_descriptors()) {
- new_map = Map::CopyDropDescriptors(map);
+ new_map = CopyDropDescriptors(map);
} else {
- new_map = Map::Copy(map);
+ new_map = Copy(map);
}
- Handle<TransitionArray> transitions =
- Map::AddTransition(map, isolate->factory()->observed_symbol(), new_map,
- FULL_TRANSITION);
+ Handle<TransitionArray> transitions = TransitionArray::CopyInsert(
+ map, isolate->factory()->observed_symbol(), new_map, FULL_TRANSITION);
map->set_transitions(*transitions);
@@ -6962,127 +7518,127 @@ Handle<Map> Map::CopyForObserved(Handle<Map> map) {
}
-MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() {
- if (pre_allocated_property_fields() == 0) return CopyDropDescriptors();
+Handle<Map> Map::Copy(Handle<Map> map) {
+ Handle<DescriptorArray> descriptors(map->instance_descriptors());
+ int number_of_own_descriptors = map->NumberOfOwnDescriptors();
+ Handle<DescriptorArray> new_descriptors =
+ DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors);
+ return CopyReplaceDescriptors(
+ map, new_descriptors, OMIT_TRANSITION, MaybeHandle<Name>());
+}
- // If the map has pre-allocated properties always start out with a descriptor
- // array describing these properties.
- ASSERT(constructor()->IsJSFunction());
- JSFunction* ctor = JSFunction::cast(constructor());
- Map* map = ctor->initial_map();
- DescriptorArray* descriptors = map->instance_descriptors();
- int number_of_own_descriptors = map->NumberOfOwnDescriptors();
- DescriptorArray* new_descriptors;
- MaybeObject* maybe_descriptors =
- descriptors->CopyUpTo(number_of_own_descriptors);
- if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
+Handle<Map> Map::Create(Handle<JSFunction> constructor,
+ int extra_inobject_properties) {
+ Handle<Map> copy = Copy(handle(constructor->initial_map()));
- return CopyReplaceDescriptors(new_descriptors, OMIT_TRANSITION);
-}
+ // Check that we do not overflow the instance size when adding the
+ // extra inobject properties.
+ int instance_size_delta = extra_inobject_properties * kPointerSize;
+ int max_instance_size_delta =
+ JSObject::kMaxInstanceSize - copy->instance_size();
+ int max_extra_properties = max_instance_size_delta >> kPointerSizeLog2;
+ // If the instance size overflows, we allocate as many properties as we can as
+ // inobject properties.
+ if (extra_inobject_properties > max_extra_properties) {
+ instance_size_delta = max_instance_size_delta;
+ extra_inobject_properties = max_extra_properties;
+ }
-Handle<Map> Map::Copy(Handle<Map> map) {
- CALL_HEAP_FUNCTION(map->GetIsolate(), map->Copy(), Map);
+ // Adjust the map with the extra inobject properties.
+ int inobject_properties =
+ copy->inobject_properties() + extra_inobject_properties;
+ copy->set_inobject_properties(inobject_properties);
+ copy->set_unused_property_fields(inobject_properties);
+ copy->set_instance_size(copy->instance_size() + instance_size_delta);
+ copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy));
+ return copy;
}
-MaybeObject* Map::Copy() {
- DescriptorArray* descriptors = instance_descriptors();
- DescriptorArray* new_descriptors;
- int number_of_own_descriptors = NumberOfOwnDescriptors();
- MaybeObject* maybe_descriptors =
- descriptors->CopyUpTo(number_of_own_descriptors);
- if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
-
- return CopyReplaceDescriptors(new_descriptors, OMIT_TRANSITION);
+Handle<Map> Map::CopyForFreeze(Handle<Map> map) {
+ int num_descriptors = map->NumberOfOwnDescriptors();
+ Isolate* isolate = map->GetIsolate();
+ Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes(
+ handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN);
+ Handle<Map> new_map = Map::CopyReplaceDescriptors(
+ map, new_desc, INSERT_TRANSITION, isolate->factory()->frozen_symbol());
+ new_map->freeze();
+ new_map->set_is_extensible(false);
+ new_map->set_elements_kind(DICTIONARY_ELEMENTS);
+ return new_map;
}
-MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor,
- TransitionFlag flag) {
- DescriptorArray* descriptors = instance_descriptors();
+Handle<Map> Map::CopyAddDescriptor(Handle<Map> map,
+ Descriptor* descriptor,
+ TransitionFlag flag) {
+ Handle<DescriptorArray> descriptors(map->instance_descriptors());
// Ensure the key is unique.
- MaybeObject* maybe_failure = descriptor->KeyToUniqueName();
- if (maybe_failure->IsFailure()) return maybe_failure;
-
- int old_size = NumberOfOwnDescriptors();
- int new_size = old_size + 1;
+ descriptor->KeyToUniqueName();
if (flag == INSERT_TRANSITION &&
- owns_descriptors() &&
- CanHaveMoreTransitions()) {
- return ShareDescriptor(descriptors, descriptor);
- }
-
- DescriptorArray* new_descriptors;
- MaybeObject* maybe_descriptors =
- DescriptorArray::Allocate(GetIsolate(), old_size, 1);
- if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
-
- DescriptorArray::WhitenessWitness witness(new_descriptors);
-
- // Copy the descriptors, inserting a descriptor.
- for (int i = 0; i < old_size; ++i) {
- new_descriptors->CopyFrom(i, descriptors, i, witness);
+ map->owns_descriptors() &&
+ map->CanHaveMoreTransitions()) {
+ return ShareDescriptor(map, descriptors, descriptor);
}
- if (old_size != descriptors->number_of_descriptors()) {
- new_descriptors->SetNumberOfDescriptors(new_size);
- new_descriptors->Set(old_size, descriptor, witness);
- new_descriptors->Sort();
- } else {
- new_descriptors->Append(descriptor, witness);
- }
+ Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
+ descriptors, map->NumberOfOwnDescriptors(), 1);
+ new_descriptors->Append(descriptor);
- Name* key = descriptor->GetKey();
- return CopyReplaceDescriptors(new_descriptors, flag, key, SIMPLE_TRANSITION);
+ return CopyReplaceDescriptors(
+ map, new_descriptors, flag, descriptor->GetKey(), SIMPLE_TRANSITION);
}
-MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor,
- TransitionFlag flag) {
- DescriptorArray* old_descriptors = instance_descriptors();
+Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map,
+ Descriptor* descriptor,
+ TransitionFlag flag) {
+ Handle<DescriptorArray> old_descriptors(map->instance_descriptors());
// Ensure the key is unique.
- MaybeObject* maybe_result = descriptor->KeyToUniqueName();
- if (maybe_result->IsFailure()) return maybe_result;
+ descriptor->KeyToUniqueName();
// We replace the key if it is already present.
- int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this);
+ int index = old_descriptors->SearchWithCache(*descriptor->GetKey(), *map);
if (index != DescriptorArray::kNotFound) {
- return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag);
+ return CopyReplaceDescriptor(map, old_descriptors, descriptor, index, flag);
}
- return CopyAddDescriptor(descriptor, flag);
+ return CopyAddDescriptor(map, descriptor, flag);
}
-Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
+Handle<DescriptorArray> DescriptorArray::CopyUpTo(
Handle<DescriptorArray> desc,
int enumeration_index,
- PropertyAttributes attributes) {
- CALL_HEAP_FUNCTION(desc->GetIsolate(),
- desc->CopyUpToAddAttributes(enumeration_index, attributes),
- DescriptorArray);
+ int slack) {
+ return DescriptorArray::CopyUpToAddAttributes(
+ desc, enumeration_index, NONE, slack);
}
-MaybeObject* DescriptorArray::CopyUpToAddAttributes(
- int enumeration_index, PropertyAttributes attributes) {
- if (enumeration_index == 0) return GetHeap()->empty_descriptor_array();
+Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
+ Handle<DescriptorArray> desc,
+ int enumeration_index,
+ PropertyAttributes attributes,
+ int slack) {
+ if (enumeration_index + slack == 0) {
+ return desc->GetIsolate()->factory()->empty_descriptor_array();
+ }
int size = enumeration_index;
- DescriptorArray* descriptors;
- MaybeObject* maybe_descriptors = Allocate(GetIsolate(), size);
- if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
- DescriptorArray::WhitenessWitness witness(descriptors);
+ Handle<DescriptorArray> descriptors =
+ DescriptorArray::Allocate(desc->GetIsolate(), size, slack);
+ DescriptorArray::WhitenessWitness witness(*descriptors);
if (attributes != NONE) {
for (int i = 0; i < size; ++i) {
- Object* value = GetValue(i);
- PropertyDetails details = GetDetails(i);
+ Object* value = desc->GetValue(i);
+ PropertyDetails details = desc->GetDetails(i);
int mask = DONT_DELETE | DONT_ENUM;
// READ_ONLY is an invalid attribute for JS setters/getters.
if (details.type() != CALLBACKS || !value->IsAccessorPair()) {
@@ -7090,59 +7646,44 @@ MaybeObject* DescriptorArray::CopyUpToAddAttributes(
}
details = details.CopyAddAttributes(
static_cast<PropertyAttributes>(attributes & mask));
- Descriptor desc(GetKey(i), value, details);
- descriptors->Set(i, &desc, witness);
+ Descriptor inner_desc(handle(desc->GetKey(i)),
+ handle(value, desc->GetIsolate()),
+ details);
+ descriptors->Set(i, &inner_desc, witness);
}
} else {
for (int i = 0; i < size; ++i) {
- descriptors->CopyFrom(i, this, i, witness);
+ descriptors->CopyFrom(i, *desc, witness);
}
}
- if (number_of_descriptors() != enumeration_index) descriptors->Sort();
+ if (desc->number_of_descriptors() != enumeration_index) descriptors->Sort();
return descriptors;
}
-MaybeObject* Map::CopyReplaceDescriptor(DescriptorArray* descriptors,
- Descriptor* descriptor,
- int insertion_index,
- TransitionFlag flag) {
+Handle<Map> Map::CopyReplaceDescriptor(Handle<Map> map,
+ Handle<DescriptorArray> descriptors,
+ Descriptor* descriptor,
+ int insertion_index,
+ TransitionFlag flag) {
// Ensure the key is unique.
- MaybeObject* maybe_failure = descriptor->KeyToUniqueName();
- if (maybe_failure->IsFailure()) return maybe_failure;
-
- Name* key = descriptor->GetKey();
- ASSERT(key == descriptors->GetKey(insertion_index));
-
- int new_size = NumberOfOwnDescriptors();
- ASSERT(0 <= insertion_index && insertion_index < new_size);
-
- ASSERT_LT(insertion_index, new_size);
+ descriptor->KeyToUniqueName();
- DescriptorArray* new_descriptors;
- MaybeObject* maybe_descriptors =
- DescriptorArray::Allocate(GetIsolate(), new_size);
- if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
- DescriptorArray::WhitenessWitness witness(new_descriptors);
+ Handle<Name> key = descriptor->GetKey();
+ ASSERT(*key == descriptors->GetKey(insertion_index));
- for (int i = 0; i < new_size; ++i) {
- if (i == insertion_index) {
- new_descriptors->Set(i, descriptor, witness);
- } else {
- new_descriptors->CopyFrom(i, descriptors, i, witness);
- }
- }
+ Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
+ descriptors, map->NumberOfOwnDescriptors());
- // Re-sort if descriptors were removed.
- if (new_size != descriptors->length()) new_descriptors->Sort();
+ new_descriptors->Replace(insertion_index, descriptor);
SimpleTransitionFlag simple_flag =
(insertion_index == descriptors->number_of_descriptors() - 1)
? SIMPLE_TRANSITION
: FULL_TRANSITION;
- return CopyReplaceDescriptors(new_descriptors, flag, key, simple_flag);
+ return CopyReplaceDescriptors(map, new_descriptors, flag, key, simple_flag);
}
@@ -7150,23 +7691,16 @@ void Map::UpdateCodeCache(Handle<Map> map,
Handle<Name> name,
Handle<Code> code) {
Isolate* isolate = map->GetIsolate();
- CALL_HEAP_FUNCTION_VOID(isolate,
- map->UpdateCodeCache(*name, *code));
-}
-
-
-MaybeObject* Map::UpdateCodeCache(Name* name, Code* code) {
+ HandleScope scope(isolate);
// Allocate the code cache if not present.
- if (code_cache()->IsFixedArray()) {
- Object* result;
- { MaybeObject* maybe_result = GetHeap()->AllocateCodeCache();
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- set_code_cache(result);
+ if (map->code_cache()->IsFixedArray()) {
+ Handle<Object> result = isolate->factory()->NewCodeCache();
+ map->set_code_cache(*result);
}
// Update the code cache.
- return CodeCache::cast(code_cache())->Update(name, code);
+ Handle<CodeCache> code_cache(CodeCache::cast(map->code_cache()), isolate);
+ CodeCache::Update(code_cache, name, code);
}
@@ -7197,74 +7731,92 @@ void Map::RemoveFromCodeCache(Name* name, Code* code, int index) {
}
-// An iterator over all map transitions in an descriptor array, reusing the map
-// field of the contens array while it is running.
+// An iterator over all map transitions in an descriptor array, reusing the
+// constructor field of the map while it is running. Negative values in
+// the constructor field indicate an active map transition iteration. The
+// original constructor is restored after iterating over all entries.
class IntrusiveMapTransitionIterator {
public:
- explicit IntrusiveMapTransitionIterator(TransitionArray* transition_array)
- : transition_array_(transition_array) { }
+ IntrusiveMapTransitionIterator(
+ Map* map, TransitionArray* transition_array, Object* constructor)
+ : map_(map),
+ transition_array_(transition_array),
+ constructor_(constructor) { }
- void Start() {
- ASSERT(!IsIterating());
- *TransitionArrayHeader() = Smi::FromInt(0);
+ void StartIfNotStarted() {
+ ASSERT(!(*IteratorField())->IsSmi() || IsIterating());
+ if (!(*IteratorField())->IsSmi()) {
+ ASSERT(*IteratorField() == constructor_);
+ *IteratorField() = Smi::FromInt(-1);
+ }
}
bool IsIterating() {
- return (*TransitionArrayHeader())->IsSmi();
+ return (*IteratorField())->IsSmi() &&
+ Smi::cast(*IteratorField())->value() < 0;
}
Map* Next() {
ASSERT(IsIterating());
- int index = Smi::cast(*TransitionArrayHeader())->value();
+ int value = Smi::cast(*IteratorField())->value();
+ int index = -value - 1;
int number_of_transitions = transition_array_->number_of_transitions();
while (index < number_of_transitions) {
- *TransitionArrayHeader() = Smi::FromInt(index + 1);
+ *IteratorField() = Smi::FromInt(value - 1);
return transition_array_->GetTarget(index);
}
- *TransitionArrayHeader() = transition_array_->GetHeap()->fixed_array_map();
+ *IteratorField() = constructor_;
return NULL;
}
private:
- Object** TransitionArrayHeader() {
- return HeapObject::RawField(transition_array_, TransitionArray::kMapOffset);
+ Object** IteratorField() {
+ return HeapObject::RawField(map_, Map::kConstructorOffset);
}
+ Map* map_;
TransitionArray* transition_array_;
+ Object* constructor_;
};
-// An iterator over all prototype transitions, reusing the map field of the
-// underlying array while it is running.
+// An iterator over all prototype transitions, reusing the constructor field
+// of the map while it is running. Positive values in the constructor field
+// indicate an active prototype transition iteration. The original constructor
+// is restored after iterating over all entries.
class IntrusivePrototypeTransitionIterator {
public:
- explicit IntrusivePrototypeTransitionIterator(HeapObject* proto_trans)
- : proto_trans_(proto_trans) { }
+ IntrusivePrototypeTransitionIterator(
+ Map* map, HeapObject* proto_trans, Object* constructor)
+ : map_(map), proto_trans_(proto_trans), constructor_(constructor) { }
- void Start() {
- ASSERT(!IsIterating());
- *Header() = Smi::FromInt(0);
+ void StartIfNotStarted() {
+ if (!(*IteratorField())->IsSmi()) {
+ ASSERT(*IteratorField() == constructor_);
+ *IteratorField() = Smi::FromInt(0);
+ }
}
bool IsIterating() {
- return (*Header())->IsSmi();
+ return (*IteratorField())->IsSmi() &&
+ Smi::cast(*IteratorField())->value() >= 0;
}
Map* Next() {
ASSERT(IsIterating());
- int transitionNumber = Smi::cast(*Header())->value();
+ int transitionNumber = Smi::cast(*IteratorField())->value();
if (transitionNumber < NumberOfTransitions()) {
- *Header() = Smi::FromInt(transitionNumber + 1);
+ *IteratorField() = Smi::FromInt(transitionNumber + 1);
return GetTransition(transitionNumber);
}
- *Header() = proto_trans_->GetHeap()->fixed_array_map();
+ *IteratorField() = constructor_;
return NULL;
}
private:
- Object** Header() {
- return HeapObject::RawField(proto_trans_, FixedArray::kMapOffset);
+ Object** IteratorField() {
+ return HeapObject::RawField(map_, Map::kConstructorOffset);
}
int NumberOfTransitions() {
@@ -7284,29 +7836,33 @@ class IntrusivePrototypeTransitionIterator {
transitionNumber * Map::kProtoTransitionElementsPerEntry;
}
+ Map* map_;
HeapObject* proto_trans_;
+ Object* constructor_;
};
// To traverse the transition tree iteratively, we have to store two kinds of
// information in a map: The parent map in the traversal and which children of a
// node have already been visited. To do this without additional memory, we
-// temporarily reuse two maps with known values:
+// temporarily reuse two fields with known values:
//
// (1) The map of the map temporarily holds the parent, and is restored to the
// meta map afterwards.
//
// (2) The info which children have already been visited depends on which part
-// of the map we currently iterate:
+// of the map we currently iterate. We use the constructor field of the
+// map to store the current index. We can do that because the constructor
+// is the same for all involved maps.
//
// (a) If we currently follow normal map transitions, we temporarily store
-// the current index in the map of the FixedArray of the desciptor
-// array's contents, and restore it to the fixed array map afterwards.
-// Note that a single descriptor can have 0, 1, or 2 transitions.
+// the current index in the constructor field, and restore it to the
+// original constructor afterwards. Note that a single descriptor can
+// have 0, 1, or 2 transitions.
//
// (b) If we currently follow prototype transitions, we temporarily store
-// the current index in the map of the FixedArray holding the prototype
-// transitions, and restore it to the fixed array map afterwards.
+// the current index in the constructor field, and restore it to the
+// original constructor afterwards.
//
// Note that the child iterator is just a concatenation of two iterators: One
// iterating over map transitions and one iterating over prototype transisitons.
@@ -7323,38 +7879,29 @@ class TraversableMap : public Map {
return old_parent;
}
- // Start iterating over this map's children, possibly destroying a FixedArray
- // map (see explanation above).
- void ChildIteratorStart() {
- if (HasTransitionArray()) {
- if (HasPrototypeTransitions()) {
- IntrusivePrototypeTransitionIterator(GetPrototypeTransitions()).Start();
- }
-
- IntrusiveMapTransitionIterator(transitions()).Start();
- }
- }
-
// If we have an unvisited child map, return that one and advance. If we have
- // none, return NULL and reset any destroyed FixedArray maps.
- TraversableMap* ChildIteratorNext() {
- TransitionArray* transition_array = unchecked_transition_array();
- if (!transition_array->map()->IsSmi() &&
- !transition_array->IsTransitionArray()) {
- return NULL;
- }
+ // none, return NULL and restore the overwritten constructor field.
+ TraversableMap* ChildIteratorNext(Object* constructor) {
+ if (!HasTransitionArray()) return NULL;
+ TransitionArray* transition_array = transitions();
if (transition_array->HasPrototypeTransitions()) {
HeapObject* proto_transitions =
- transition_array->UncheckedPrototypeTransitions();
- IntrusivePrototypeTransitionIterator proto_iterator(proto_transitions);
+ transition_array->GetPrototypeTransitions();
+ IntrusivePrototypeTransitionIterator proto_iterator(this,
+ proto_transitions,
+ constructor);
+ proto_iterator.StartIfNotStarted();
if (proto_iterator.IsIterating()) {
Map* next = proto_iterator.Next();
if (next != NULL) return static_cast<TraversableMap*>(next);
}
}
- IntrusiveMapTransitionIterator transition_iterator(transition_array);
+ IntrusiveMapTransitionIterator transition_iterator(this,
+ transition_array,
+ constructor);
+ transition_iterator.StartIfNotStarted();
if (transition_iterator.IsIterating()) {
Map* next = transition_iterator.Next();
if (next != NULL) return static_cast<TraversableMap*>(next);
@@ -7368,12 +7915,16 @@ class TraversableMap : public Map {
// Traverse the transition tree in postorder without using the C++ stack by
// doing pointer reversal.
void Map::TraverseTransitionTree(TraverseCallback callback, void* data) {
+ // Make sure that we do not allocate in the callback.
+ DisallowHeapAllocation no_allocation;
+
TraversableMap* current = static_cast<TraversableMap*>(this);
- current->ChildIteratorStart();
+ // Get the root constructor here to restore it later when finished iterating
+ // over maps.
+ Object* root_constructor = constructor();
while (true) {
- TraversableMap* child = current->ChildIteratorNext();
+ TraversableMap* child = current->ChildIteratorNext(root_constructor);
if (child != NULL) {
- child->ChildIteratorStart();
child->SetParent(current);
current = child;
} else {
@@ -7386,30 +7937,29 @@ void Map::TraverseTransitionTree(TraverseCallback callback, void* data) {
}
-MaybeObject* CodeCache::Update(Name* name, Code* code) {
+void CodeCache::Update(
+ Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code) {
// The number of monomorphic stubs for normal load/store/call IC's can grow to
// a large number and therefore they need to go into a hash table. They are
// used to load global properties from cells.
if (code->type() == Code::NORMAL) {
// Make sure that a hash table is allocated for the normal load code cache.
- if (normal_type_cache()->IsUndefined()) {
- Object* result;
- { MaybeObject* maybe_result =
- CodeCacheHashTable::Allocate(GetHeap(),
- CodeCacheHashTable::kInitialSize);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- set_normal_type_cache(result);
+ if (code_cache->normal_type_cache()->IsUndefined()) {
+ Handle<Object> result =
+ CodeCacheHashTable::New(code_cache->GetIsolate(),
+ CodeCacheHashTable::kInitialSize);
+ code_cache->set_normal_type_cache(*result);
}
- return UpdateNormalTypeCache(name, code);
+ UpdateNormalTypeCache(code_cache, name, code);
} else {
- ASSERT(default_cache()->IsFixedArray());
- return UpdateDefaultCache(name, code);
+ ASSERT(code_cache->default_cache()->IsFixedArray());
+ UpdateDefaultCache(code_cache, name, code);
}
}
-MaybeObject* CodeCache::UpdateDefaultCache(Name* name, Code* code) {
+void CodeCache::UpdateDefaultCache(
+ Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code) {
// When updating the default code cache we disregard the type encoded in the
// flags. This allows call constant stubs to overwrite call field
// stubs, etc.
@@ -7417,37 +7967,40 @@ MaybeObject* CodeCache::UpdateDefaultCache(Name* name, Code* code) {
// First check whether we can update existing code cache without
// extending it.
- FixedArray* cache = default_cache();
+ Handle<FixedArray> cache = handle(code_cache->default_cache());
int length = cache->length();
- int deleted_index = -1;
- for (int i = 0; i < length; i += kCodeCacheEntrySize) {
- Object* key = cache->get(i);
- if (key->IsNull()) {
- if (deleted_index < 0) deleted_index = i;
- continue;
- }
- if (key->IsUndefined()) {
- if (deleted_index >= 0) i = deleted_index;
- cache->set(i + kCodeCacheEntryNameOffset, name);
- cache->set(i + kCodeCacheEntryCodeOffset, code);
- return this;
- }
- if (name->Equals(Name::cast(key))) {
- Code::Flags found =
- Code::cast(cache->get(i + kCodeCacheEntryCodeOffset))->flags();
- if (Code::RemoveTypeFromFlags(found) == flags) {
- cache->set(i + kCodeCacheEntryCodeOffset, code);
- return this;
+ {
+ DisallowHeapAllocation no_alloc;
+ int deleted_index = -1;
+ for (int i = 0; i < length; i += kCodeCacheEntrySize) {
+ Object* key = cache->get(i);
+ if (key->IsNull()) {
+ if (deleted_index < 0) deleted_index = i;
+ continue;
+ }
+ if (key->IsUndefined()) {
+ if (deleted_index >= 0) i = deleted_index;
+ cache->set(i + kCodeCacheEntryNameOffset, *name);
+ cache->set(i + kCodeCacheEntryCodeOffset, *code);
+ return;
+ }
+ if (name->Equals(Name::cast(key))) {
+ Code::Flags found =
+ Code::cast(cache->get(i + kCodeCacheEntryCodeOffset))->flags();
+ if (Code::RemoveTypeFromFlags(found) == flags) {
+ cache->set(i + kCodeCacheEntryCodeOffset, *code);
+ return;
+ }
}
}
- }
- // Reached the end of the code cache. If there were deleted
- // elements, reuse the space for the first of them.
- if (deleted_index >= 0) {
- cache->set(deleted_index + kCodeCacheEntryNameOffset, name);
- cache->set(deleted_index + kCodeCacheEntryCodeOffset, code);
- return this;
+ // Reached the end of the code cache. If there were deleted
+ // elements, reuse the space for the first of them.
+ if (deleted_index >= 0) {
+ cache->set(deleted_index + kCodeCacheEntryNameOffset, *name);
+ cache->set(deleted_index + kCodeCacheEntryCodeOffset, *code);
+ return;
+ }
}
// Extend the code cache with some new entries (at least one). Must be a
@@ -7455,29 +8008,22 @@ MaybeObject* CodeCache::UpdateDefaultCache(Name* name, Code* code) {
int new_length = length + ((length >> 1)) + kCodeCacheEntrySize;
new_length = new_length - new_length % kCodeCacheEntrySize;
ASSERT((new_length % kCodeCacheEntrySize) == 0);
- Object* result;
- { MaybeObject* maybe_result = cache->CopySize(new_length);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
+ cache = FixedArray::CopySize(cache, new_length);
// Add the (name, code) pair to the new cache.
- cache = FixedArray::cast(result);
- cache->set(length + kCodeCacheEntryNameOffset, name);
- cache->set(length + kCodeCacheEntryCodeOffset, code);
- set_default_cache(cache);
- return this;
+ cache->set(length + kCodeCacheEntryNameOffset, *name);
+ cache->set(length + kCodeCacheEntryCodeOffset, *code);
+ code_cache->set_default_cache(*cache);
}
-MaybeObject* CodeCache::UpdateNormalTypeCache(Name* name, Code* code) {
+void CodeCache::UpdateNormalTypeCache(
+ Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code) {
// Adding a new entry can cause a new cache to be allocated.
- CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache());
- Object* new_cache;
- { MaybeObject* maybe_new_cache = cache->Put(name, code);
- if (!maybe_new_cache->ToObject(&new_cache)) return maybe_new_cache;
- }
- set_normal_type_cache(new_cache);
- return this;
+ Handle<CodeCacheHashTable> cache(
+ CodeCacheHashTable::cast(code_cache->normal_type_cache()));
+ Handle<Object> new_cache = CodeCacheHashTable::Put(cache, name, code);
+ code_cache->set_normal_type_cache(*new_cache);
}
@@ -7561,14 +8107,13 @@ void CodeCache::RemoveByIndex(Object* name, Code* code, int index) {
// lookup not to create a new entry.
class CodeCacheHashTableKey : public HashTableKey {
public:
- CodeCacheHashTableKey(Name* name, Code::Flags flags)
- : name_(name), flags_(flags), code_(NULL) { }
+ CodeCacheHashTableKey(Handle<Name> name, Code::Flags flags)
+ : name_(name), flags_(flags), code_() { }
- CodeCacheHashTableKey(Name* name, Code* code)
+ CodeCacheHashTableKey(Handle<Name> name, Handle<Code> code)
: name_(name), flags_(code->flags()), code_(code) { }
-
- bool IsMatch(Object* other) {
+ bool IsMatch(Object* other) V8_OVERRIDE {
if (!other->IsFixedArray()) return false;
FixedArray* pair = FixedArray::cast(other);
Name* name = Name::cast(pair->get(0));
@@ -7583,68 +8128,59 @@ class CodeCacheHashTableKey : public HashTableKey {
return name->Hash() ^ flags;
}
- uint32_t Hash() { return NameFlagsHashHelper(name_, flags_); }
+ uint32_t Hash() V8_OVERRIDE { return NameFlagsHashHelper(*name_, flags_); }
- uint32_t HashForObject(Object* obj) {
+ uint32_t HashForObject(Object* obj) V8_OVERRIDE {
FixedArray* pair = FixedArray::cast(obj);
Name* name = Name::cast(pair->get(0));
Code* code = Code::cast(pair->get(1));
return NameFlagsHashHelper(name, code->flags());
}
- MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) {
- ASSERT(code_ != NULL);
- Object* obj;
- { MaybeObject* maybe_obj = heap->AllocateFixedArray(2);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- FixedArray* pair = FixedArray::cast(obj);
- pair->set(0, name_);
- pair->set(1, code_);
+ MUST_USE_RESULT Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE {
+ Handle<Code> code = code_.ToHandleChecked();
+ Handle<FixedArray> pair = isolate->factory()->NewFixedArray(2);
+ pair->set(0, *name_);
+ pair->set(1, *code);
return pair;
}
private:
- Name* name_;
+ Handle<Name> name_;
Code::Flags flags_;
// TODO(jkummerow): We should be able to get by without this.
- Code* code_;
+ MaybeHandle<Code> code_;
};
Object* CodeCacheHashTable::Lookup(Name* name, Code::Flags flags) {
- CodeCacheHashTableKey key(name, flags);
+ DisallowHeapAllocation no_alloc;
+ CodeCacheHashTableKey key(handle(name), flags);
int entry = FindEntry(&key);
if (entry == kNotFound) return GetHeap()->undefined_value();
return get(EntryToIndex(entry) + 1);
}
-MaybeObject* CodeCacheHashTable::Put(Name* name, Code* code) {
+Handle<CodeCacheHashTable> CodeCacheHashTable::Put(
+ Handle<CodeCacheHashTable> cache, Handle<Name> name, Handle<Code> code) {
CodeCacheHashTableKey key(name, code);
- Object* obj;
- { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- // Don't use |this|, as the table might have grown.
- CodeCacheHashTable* cache = reinterpret_cast<CodeCacheHashTable*>(obj);
+ Handle<CodeCacheHashTable> new_cache = EnsureCapacity(cache, 1, &key);
- int entry = cache->FindInsertionEntry(key.Hash());
- Object* k;
- { MaybeObject* maybe_k = key.AsObject(GetHeap());
- if (!maybe_k->ToObject(&k)) return maybe_k;
- }
+ int entry = new_cache->FindInsertionEntry(key.Hash());
+ Handle<Object> k = key.AsHandle(cache->GetIsolate());
- cache->set(EntryToIndex(entry), k);
- cache->set(EntryToIndex(entry) + 1, code);
- cache->ElementAdded();
- return cache;
+ new_cache->set(EntryToIndex(entry), *k);
+ new_cache->set(EntryToIndex(entry) + 1, *code);
+ new_cache->ElementAdded();
+ return new_cache;
}
int CodeCacheHashTable::GetIndex(Name* name, Code::Flags flags) {
- CodeCacheHashTableKey key(name, flags);
+ DisallowHeapAllocation no_alloc;
+ CodeCacheHashTableKey key(handle(name), flags);
int entry = FindEntry(&key);
return (entry == kNotFound) ? -1 : entry;
}
@@ -7659,41 +8195,27 @@ void CodeCacheHashTable::RemoveByIndex(int index) {
}
-void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> cache,
+void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> code_cache,
MapHandleList* maps,
Code::Flags flags,
Handle<Code> code) {
- Isolate* isolate = cache->GetIsolate();
- CALL_HEAP_FUNCTION_VOID(isolate, cache->Update(maps, flags, *code));
-}
-
-
-MaybeObject* PolymorphicCodeCache::Update(MapHandleList* maps,
- Code::Flags flags,
- Code* code) {
- // Initialize cache if necessary.
- if (cache()->IsUndefined()) {
- Object* result;
- { MaybeObject* maybe_result =
- PolymorphicCodeCacheHashTable::Allocate(
- GetHeap(),
- PolymorphicCodeCacheHashTable::kInitialSize);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- set_cache(result);
+ Isolate* isolate = code_cache->GetIsolate();
+ if (code_cache->cache()->IsUndefined()) {
+ Handle<PolymorphicCodeCacheHashTable> result =
+ PolymorphicCodeCacheHashTable::New(
+ isolate,
+ PolymorphicCodeCacheHashTable::kInitialSize);
+ code_cache->set_cache(*result);
} else {
// This entry shouldn't be contained in the cache yet.
- ASSERT(PolymorphicCodeCacheHashTable::cast(cache())
+ ASSERT(PolymorphicCodeCacheHashTable::cast(code_cache->cache())
->Lookup(maps, flags)->IsUndefined());
}
- PolymorphicCodeCacheHashTable* hash_table =
- PolymorphicCodeCacheHashTable::cast(cache());
- Object* new_cache;
- { MaybeObject* maybe_new_cache = hash_table->Put(maps, flags, code);
- if (!maybe_new_cache->ToObject(&new_cache)) return maybe_new_cache;
- }
- set_cache(new_cache);
- return this;
+ Handle<PolymorphicCodeCacheHashTable> hash_table =
+ handle(PolymorphicCodeCacheHashTable::cast(code_cache->cache()));
+ Handle<PolymorphicCodeCacheHashTable> new_cache =
+ PolymorphicCodeCacheHashTable::Put(hash_table, maps, flags, code);
+ code_cache->set_cache(*new_cache);
}
@@ -7719,7 +8241,7 @@ class PolymorphicCodeCacheHashTableKey : public HashTableKey {
: maps_(maps),
code_flags_(code_flags) {}
- bool IsMatch(Object* other) {
+ bool IsMatch(Object* other) V8_OVERRIDE {
MapHandleList other_maps(kDefaultListAllocationSize);
int other_flags;
FromObject(other, &other_flags, &other_maps);
@@ -7754,27 +8276,23 @@ class PolymorphicCodeCacheHashTableKey : public HashTableKey {
return hash;
}
- uint32_t Hash() {
+ uint32_t Hash() V8_OVERRIDE {
return MapsHashHelper(maps_, code_flags_);
}
- uint32_t HashForObject(Object* obj) {
+ uint32_t HashForObject(Object* obj) V8_OVERRIDE {
MapHandleList other_maps(kDefaultListAllocationSize);
int other_flags;
FromObject(obj, &other_flags, &other_maps);
return MapsHashHelper(&other_maps, other_flags);
}
- MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) {
- Object* obj;
+ MUST_USE_RESULT Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE {
// The maps in |maps_| must be copied to a newly allocated FixedArray,
// both because the referenced MapList is short-lived, and because C++
// objects can't be stored in the heap anyway.
- { MaybeObject* maybe_obj =
- heap->AllocateUninitializedFixedArray(maps_->length() + 1);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- FixedArray* list = FixedArray::cast(obj);
+ Handle<FixedArray> list =
+ isolate->factory()->NewUninitializedFixedArray(maps_->length() + 1);
list->set(0, Smi::FromInt(code_flags_));
for (int i = 0; i < maps_->length(); ++i) {
list->set(i + 1, *maps_->at(i));
@@ -7802,30 +8320,28 @@ class PolymorphicCodeCacheHashTableKey : public HashTableKey {
Object* PolymorphicCodeCacheHashTable::Lookup(MapHandleList* maps,
- int code_flags) {
- PolymorphicCodeCacheHashTableKey key(maps, code_flags);
+ int code_kind) {
+ DisallowHeapAllocation no_alloc;
+ PolymorphicCodeCacheHashTableKey key(maps, code_kind);
int entry = FindEntry(&key);
if (entry == kNotFound) return GetHeap()->undefined_value();
return get(EntryToIndex(entry) + 1);
}
-MaybeObject* PolymorphicCodeCacheHashTable::Put(MapHandleList* maps,
- int code_flags,
- Code* code) {
- PolymorphicCodeCacheHashTableKey key(maps, code_flags);
- Object* obj;
- { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- PolymorphicCodeCacheHashTable* cache =
- reinterpret_cast<PolymorphicCodeCacheHashTable*>(obj);
+Handle<PolymorphicCodeCacheHashTable> PolymorphicCodeCacheHashTable::Put(
+ Handle<PolymorphicCodeCacheHashTable> hash_table,
+ MapHandleList* maps,
+ int code_kind,
+ Handle<Code> code) {
+ PolymorphicCodeCacheHashTableKey key(maps, code_kind);
+ Handle<PolymorphicCodeCacheHashTable> cache =
+ EnsureCapacity(hash_table, 1, &key);
int entry = cache->FindInsertionEntry(key.Hash());
- { MaybeObject* maybe_obj = key.AsObject(GetHeap());
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- cache->set(EntryToIndex(entry), obj);
- cache->set(EntryToIndex(entry) + 1, code);
+
+ Handle<Object> obj = key.AsHandle(hash_table->GetIsolate());
+ cache->set(EntryToIndex(entry), *obj);
+ cache->set(EntryToIndex(entry) + 1, *code);
cache->ElementAdded();
return cache;
}
@@ -7840,14 +8356,20 @@ void FixedArray::Shrink(int new_length) {
}
-MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) {
+MaybeHandle<FixedArray> FixedArray::AddKeysFromArrayLike(
+ Handle<FixedArray> content,
+ Handle<JSObject> array) {
+ ASSERT(array->IsJSArray() || array->HasSloppyArgumentsElements());
ElementsAccessor* accessor = array->GetElementsAccessor();
- MaybeObject* maybe_result =
- accessor->AddElementsToFixedArray(array, array, this);
- FixedArray* result;
- if (!maybe_result->To<FixedArray>(&result)) return maybe_result;
+ Handle<FixedArray> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ array->GetIsolate(), result,
+ accessor->AddElementsToFixedArray(array, array, content),
+ FixedArray);
+
#ifdef ENABLE_SLOW_ASSERTS
if (FLAG_enable_slow_asserts) {
+ DisallowHeapAllocation no_allocation;
for (int i = 0; i < result->length(); i++) {
Object* current = result->get(i);
ASSERT(current->IsNumber() || current->IsName());
@@ -7858,14 +8380,22 @@ MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) {
}
-MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) {
- ElementsAccessor* accessor = ElementsAccessor::ForArray(other);
- MaybeObject* maybe_result =
- accessor->AddElementsToFixedArray(NULL, NULL, this, other);
- FixedArray* result;
- if (!maybe_result->To(&result)) return maybe_result;
+MaybeHandle<FixedArray> FixedArray::UnionOfKeys(Handle<FixedArray> first,
+ Handle<FixedArray> second) {
+ ElementsAccessor* accessor = ElementsAccessor::ForArray(second);
+ Handle<FixedArray> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ first->GetIsolate(), result,
+ accessor->AddElementsToFixedArray(
+ Handle<Object>::null(), // receiver
+ Handle<JSObject>::null(), // holder
+ first,
+ Handle<FixedArrayBase>::cast(second)),
+ FixedArray);
+
#ifdef ENABLE_SLOW_ASSERTS
if (FLAG_enable_slow_asserts) {
+ DisallowHeapAllocation no_allocation;
for (int i = 0; i < result->length(); i++) {
Object* current = result->get(i);
ASSERT(current->IsNumber() || current->IsName());
@@ -7876,24 +8406,22 @@ MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) {
}
-MaybeObject* FixedArray::CopySize(int new_length, PretenureFlag pretenure) {
- Heap* heap = GetHeap();
- if (new_length == 0) return heap->empty_fixed_array();
- Object* obj;
- { MaybeObject* maybe_obj = heap->AllocateFixedArray(new_length, pretenure);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- FixedArray* result = FixedArray::cast(obj);
+Handle<FixedArray> FixedArray::CopySize(
+ Handle<FixedArray> array, int new_length, PretenureFlag pretenure) {
+ Isolate* isolate = array->GetIsolate();
+ if (new_length == 0) return isolate->factory()->empty_fixed_array();
+ Handle<FixedArray> result =
+ isolate->factory()->NewFixedArray(new_length, pretenure);
// Copy the content
DisallowHeapAllocation no_gc;
- int len = length();
+ int len = array->length();
if (new_length < len) len = new_length;
// We are taking the map from the old fixed array so the map is sure to
// be an immortal immutable object.
- result->set_map_no_write_barrier(map());
+ result->set_map_no_write_barrier(array->map());
WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
for (int i = 0; i < len; i++) {
- result->set(i, get(i), mode);
+ result->set(i, array->get(i), mode);
}
return result;
}
@@ -7919,21 +8447,20 @@ bool FixedArray::IsEqualTo(FixedArray* other) {
#endif
-MaybeObject* DescriptorArray::Allocate(Isolate* isolate,
- int number_of_descriptors,
- int slack) {
- Heap* heap = isolate->heap();
+Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
+ int number_of_descriptors,
+ int slack) {
+ ASSERT(0 <= number_of_descriptors);
+ Factory* factory = isolate->factory();
// Do not use DescriptorArray::cast on incomplete object.
int size = number_of_descriptors + slack;
- if (size == 0) return heap->empty_descriptor_array();
- FixedArray* result;
+ if (size == 0) return factory->empty_descriptor_array();
// Allocate the array of keys.
- MaybeObject* maybe_array = heap->AllocateFixedArray(LengthFor(size));
- if (!maybe_array->To(&result)) return maybe_array;
+ Handle<FixedArray> result = factory->NewFixedArray(LengthFor(size));
result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors));
result->set(kEnumCacheIndex, Smi::FromInt(0));
- return result;
+ return Handle<DescriptorArray>::cast(result);
}
@@ -7942,6 +8469,12 @@ void DescriptorArray::ClearEnumCache() {
}
+void DescriptorArray::Replace(int index, Descriptor* descriptor) {
+ descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index));
+ Set(index, descriptor);
+}
+
+
void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
FixedArray* new_cache,
Object* new_index_cache) {
@@ -7957,138 +8490,15 @@ void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
}
-void DescriptorArray::CopyFrom(int dst_index,
+void DescriptorArray::CopyFrom(int index,
DescriptorArray* src,
- int src_index,
const WhitenessWitness& witness) {
- Object* value = src->GetValue(src_index);
- PropertyDetails details = src->GetDetails(src_index);
- Descriptor desc(src->GetKey(src_index), value, details);
- Set(dst_index, &desc, witness);
-}
-
-
-Handle<DescriptorArray> DescriptorArray::Merge(Handle<DescriptorArray> desc,
- int verbatim,
- int valid,
- int new_size,
- int modify_index,
- StoreMode store_mode,
- Handle<DescriptorArray> other) {
- CALL_HEAP_FUNCTION(desc->GetIsolate(),
- desc->Merge(verbatim, valid, new_size, modify_index,
- store_mode, *other),
- DescriptorArray);
-}
-
-
-// Generalize the |other| descriptor array by merging it into the (at least
-// partly) updated |this| descriptor array.
-// The method merges two descriptor array in three parts. Both descriptor arrays
-// are identical up to |verbatim|. They also overlap in keys up to |valid|.
-// Between |verbatim| and |valid|, the resulting descriptor type as well as the
-// representation are generalized from both |this| and |other|. Beyond |valid|,
-// the descriptors are copied verbatim from |other| up to |new_size|.
-// In case of incompatible types, the type and representation of |other| is
-// used.
-MaybeObject* DescriptorArray::Merge(int verbatim,
- int valid,
- int new_size,
- int modify_index,
- StoreMode store_mode,
- DescriptorArray* other) {
- ASSERT(verbatim <= valid);
- ASSERT(valid <= new_size);
-
- DescriptorArray* result;
- // Allocate a new descriptor array large enough to hold the required
- // descriptors, with minimally the exact same size as this descriptor array.
- MaybeObject* maybe_descriptors = DescriptorArray::Allocate(
- GetIsolate(), new_size,
- Max(new_size, other->number_of_descriptors()) - new_size);
- if (!maybe_descriptors->To(&result)) return maybe_descriptors;
- ASSERT(result->length() > length() ||
- result->NumberOfSlackDescriptors() > 0 ||
- result->number_of_descriptors() == other->number_of_descriptors());
- ASSERT(result->number_of_descriptors() == new_size);
-
- DescriptorArray::WhitenessWitness witness(result);
-
- int descriptor;
-
- // 0 -> |verbatim|
- int current_offset = 0;
- for (descriptor = 0; descriptor < verbatim; descriptor++) {
- if (GetDetails(descriptor).type() == FIELD) current_offset++;
- result->CopyFrom(descriptor, other, descriptor, witness);
- }
-
- // |verbatim| -> |valid|
- for (; descriptor < valid; descriptor++) {
- Name* key = GetKey(descriptor);
- PropertyDetails details = GetDetails(descriptor);
- PropertyDetails other_details = other->GetDetails(descriptor);
-
- if (details.type() == FIELD || other_details.type() == FIELD ||
- (store_mode == FORCE_FIELD && descriptor == modify_index) ||
- (details.type() == CONSTANT &&
- other_details.type() == CONSTANT &&
- GetValue(descriptor) != other->GetValue(descriptor))) {
- Representation representation =
- details.representation().generalize(other_details.representation());
- FieldDescriptor d(key,
- current_offset++,
- other_details.attributes(),
- representation);
- result->Set(descriptor, &d, witness);
- } else {
- result->CopyFrom(descriptor, other, descriptor, witness);
- }
- }
-
- // |valid| -> |new_size|
- for (; descriptor < new_size; descriptor++) {
- PropertyDetails details = other->GetDetails(descriptor);
- if (details.type() == FIELD ||
- (store_mode == FORCE_FIELD && descriptor == modify_index)) {
- Name* key = other->GetKey(descriptor);
- FieldDescriptor d(key,
- current_offset++,
- details.attributes(),
- details.representation());
- result->Set(descriptor, &d, witness);
- } else {
- result->CopyFrom(descriptor, other, descriptor, witness);
- }
- }
-
- result->Sort();
- return result;
-}
-
-
-// Checks whether a merge of |other| into |this| would return a copy of |this|.
-bool DescriptorArray::IsMoreGeneralThan(int verbatim,
- int valid,
- int new_size,
- DescriptorArray* other) {
- ASSERT(verbatim <= valid);
- ASSERT(valid <= new_size);
- if (valid != new_size) return false;
-
- for (int descriptor = verbatim; descriptor < valid; descriptor++) {
- PropertyDetails details = GetDetails(descriptor);
- PropertyDetails other_details = other->GetDetails(descriptor);
- if (!other_details.representation().fits_into(details.representation())) {
- return false;
- }
- if (details.type() == CONSTANT) {
- if (other_details.type() != CONSTANT) return false;
- if (GetValue(descriptor) != other->GetValue(descriptor)) return false;
- }
- }
-
- return true;
+ Object* value = src->GetValue(index);
+ PropertyDetails details = src->GetDetails(index);
+ Descriptor desc(handle(src->GetKey(index)),
+ handle(value, src->GetIsolate()),
+ details);
+ Set(index, &desc, witness);
}
@@ -8165,21 +8575,29 @@ Object* AccessorPair::GetComponent(AccessorComponent component) {
}
-MaybeObject* DeoptimizationInputData::Allocate(Isolate* isolate,
- int deopt_entry_count,
- PretenureFlag pretenure) {
+Handle<DeoptimizationInputData> DeoptimizationInputData::New(
+ Isolate* isolate,
+ int deopt_entry_count,
+ PretenureFlag pretenure) {
ASSERT(deopt_entry_count > 0);
- return isolate->heap()->AllocateFixedArray(LengthFor(deopt_entry_count),
- pretenure);
+ return Handle<DeoptimizationInputData>::cast(
+ isolate->factory()->NewFixedArray(
+ LengthFor(deopt_entry_count), pretenure));
}
-MaybeObject* DeoptimizationOutputData::Allocate(Isolate* isolate,
- int number_of_deopt_points,
- PretenureFlag pretenure) {
- if (number_of_deopt_points == 0) return isolate->heap()->empty_fixed_array();
- return isolate->heap()->AllocateFixedArray(
- LengthOfFixedArray(number_of_deopt_points), pretenure);
+Handle<DeoptimizationOutputData> DeoptimizationOutputData::New(
+ Isolate* isolate,
+ int number_of_deopt_points,
+ PretenureFlag pretenure) {
+ Handle<FixedArray> result;
+ if (number_of_deopt_points == 0) {
+ result = isolate->factory()->empty_fixed_array();
+ } else {
+ result = isolate->factory()->NewFixedArray(
+ LengthOfFixedArray(number_of_deopt_points), pretenure);
+ }
+ return Handle<DeoptimizationOutputData>::cast(result);
}
@@ -8255,7 +8673,7 @@ String::FlatContent String::GetFlatContent() {
} else {
start = ExternalAsciiString::cast(string)->GetChars();
}
- return FlatContent(Vector<const uint8_t>(start + offset, length));
+ return FlatContent(start + offset, length);
} else {
ASSERT(shape.encoding_tag() == kTwoByteStringTag);
const uc16* start;
@@ -8264,7 +8682,7 @@ String::FlatContent String::GetFlatContent() {
} else {
start = ExternalTwoByteString::cast(string)->GetChars();
}
- return FlatContent(Vector<const uc16>(start + offset, length));
+ return FlatContent(start + offset, length);
}
}
@@ -8460,34 +8878,47 @@ void FlatStringReader::PostGarbageCollection() {
}
-String* ConsStringIteratorOp::Operate(String* string,
- unsigned* offset_out,
- int32_t* type_out,
- unsigned* length_out) {
- ASSERT(string->IsConsString());
- ConsString* cons_string = ConsString::cast(string);
- // Set up search data.
+void ConsStringIteratorOp::Initialize(ConsString* cons_string, int offset) {
+ ASSERT(cons_string != NULL);
root_ = cons_string;
- consumed_ = *offset_out;
- // Now search.
- return Search(offset_out, type_out, length_out);
+ consumed_ = offset;
+ // Force stack blown condition to trigger restart.
+ depth_ = 1;
+ maximum_depth_ = kStackSize + depth_;
+ ASSERT(StackBlown());
}
-String* ConsStringIteratorOp::Search(unsigned* offset_out,
- int32_t* type_out,
- unsigned* length_out) {
+String* ConsStringIteratorOp::Continue(int* offset_out) {
+ ASSERT(depth_ != 0);
+ ASSERT_EQ(0, *offset_out);
+ bool blew_stack = StackBlown();
+ String* string = NULL;
+ // Get the next leaf if there is one.
+ if (!blew_stack) string = NextLeaf(&blew_stack);
+ // Restart search from root.
+ if (blew_stack) {
+ ASSERT(string == NULL);
+ string = Search(offset_out);
+ }
+ // Ensure future calls return null immediately.
+ if (string == NULL) Reset(NULL);
+ return string;
+}
+
+
+String* ConsStringIteratorOp::Search(int* offset_out) {
ConsString* cons_string = root_;
// Reset the stack, pushing the root string.
depth_ = 1;
maximum_depth_ = 1;
frames_[0] = cons_string;
- const unsigned consumed = consumed_;
- unsigned offset = 0;
+ const int consumed = consumed_;
+ int offset = 0;
while (true) {
// Loop until the string is found which contains the target offset.
String* string = cons_string->first();
- unsigned length = string->length();
+ int length = string->length();
int32_t type;
if (consumed < offset + length) {
// Target offset is in the left branch.
@@ -8498,7 +8929,7 @@ String* ConsStringIteratorOp::Search(unsigned* offset_out,
PushLeft(cons_string);
continue;
}
- // Tell the stack we're done decending.
+ // Tell the stack we're done descending.
AdjustMaximumDepth();
} else {
// Descend right.
@@ -8510,7 +8941,6 @@ String* ConsStringIteratorOp::Search(unsigned* offset_out,
if ((type & kStringRepresentationMask) == kConsStringTag) {
cons_string = ConsString::cast(string);
PushRight(cons_string);
- // TODO(dcarney) Add back root optimization.
continue;
}
// Need this to be updated for the current string.
@@ -8518,11 +8948,11 @@ String* ConsStringIteratorOp::Search(unsigned* offset_out,
// Account for the possibility of an empty right leaf.
// This happens only if we have asked for an offset outside the string.
if (length == 0) {
- // Reset depth so future operations will return null immediately.
- Reset();
+ // Reset so future operations will return null immediately.
+ Reset(NULL);
return NULL;
}
- // Tell the stack we're done decending.
+ // Tell the stack we're done descending.
AdjustMaximumDepth();
// Pop stack so next iteration is in correct place.
Pop();
@@ -8531,8 +8961,6 @@ String* ConsStringIteratorOp::Search(unsigned* offset_out,
// Adjust return values and exit.
consumed_ = offset + length;
*offset_out = consumed - offset;
- *type_out = type;
- *length_out = length;
return string;
}
UNREACHABLE();
@@ -8540,9 +8968,7 @@ String* ConsStringIteratorOp::Search(unsigned* offset_out,
}
-String* ConsStringIteratorOp::NextLeaf(bool* blew_stack,
- int32_t* type_out,
- unsigned* length_out) {
+String* ConsStringIteratorOp::NextLeaf(bool* blew_stack) {
while (true) {
// Tree traversal complete.
if (depth_ == 0) {
@@ -8550,7 +8976,7 @@ String* ConsStringIteratorOp::NextLeaf(bool* blew_stack,
return NULL;
}
// We've lost track of higher nodes.
- if (maximum_depth_ - depth_ == kStackSize) {
+ if (StackBlown()) {
*blew_stack = true;
return NULL;
}
@@ -8561,16 +8987,13 @@ String* ConsStringIteratorOp::NextLeaf(bool* blew_stack,
if ((type & kStringRepresentationMask) != kConsStringTag) {
// Pop stack so next iteration is in correct place.
Pop();
- unsigned length = static_cast<unsigned>(string->length());
+ int length = string->length();
// Could be a flattened ConsString.
if (length == 0) continue;
- *length_out = length;
- *type_out = type;
consumed_ += length;
return string;
}
cons_string = ConsString::cast(string);
- // TODO(dcarney) Add back root optimization.
PushRight(cons_string);
// Need to traverse all the way left.
while (true) {
@@ -8579,10 +9002,8 @@ String* ConsStringIteratorOp::NextLeaf(bool* blew_stack,
type = string->map()->instance_type();
if ((type & kStringRepresentationMask) != kConsStringTag) {
AdjustMaximumDepth();
- unsigned length = static_cast<unsigned>(string->length());
+ int length = string->length();
ASSERT(length != 0);
- *length_out = length;
- *type_out = type;
consumed_ += length;
return string;
}
@@ -8721,6 +9142,64 @@ void String::WriteToFlat(String* src,
}
+
+template <typename SourceChar>
+static void CalculateLineEndsImpl(Isolate* isolate,
+ List<int>* line_ends,
+ Vector<const SourceChar> src,
+ bool include_ending_line) {
+ const int src_len = src.length();
+ StringSearch<uint8_t, SourceChar> search(isolate, STATIC_ASCII_VECTOR("\n"));
+
+ // Find and record line ends.
+ int position = 0;
+ while (position != -1 && position < src_len) {
+ position = search.Search(src, position);
+ if (position != -1) {
+ line_ends->Add(position);
+ position++;
+ } else if (include_ending_line) {
+ // Even if the last line misses a line end, it is counted.
+ line_ends->Add(src_len);
+ return;
+ }
+ }
+}
+
+
+Handle<FixedArray> String::CalculateLineEnds(Handle<String> src,
+ bool include_ending_line) {
+ src = Flatten(src);
+ // Rough estimate of line count based on a roughly estimated average
+ // length of (unpacked) code.
+ int line_count_estimate = src->length() >> 4;
+ List<int> line_ends(line_count_estimate);
+ Isolate* isolate = src->GetIsolate();
+ { DisallowHeapAllocation no_allocation; // ensure vectors stay valid.
+ // Dispatch on type of strings.
+ String::FlatContent content = src->GetFlatContent();
+ ASSERT(content.IsFlat());
+ if (content.IsAscii()) {
+ CalculateLineEndsImpl(isolate,
+ &line_ends,
+ content.ToOneByteVector(),
+ include_ending_line);
+ } else {
+ CalculateLineEndsImpl(isolate,
+ &line_ends,
+ content.ToUC16Vector(),
+ include_ending_line);
+ }
+ }
+ int line_count = line_ends.length();
+ Handle<FixedArray> array = isolate->factory()->NewFixedArray(line_count);
+ for (int i = 0; i < line_count; i++) {
+ array->set(i, Smi::FromInt(line_ends[i]));
+ }
+ return array;
+}
+
+
// Compares the contents of two strings by reading and comparing
// int-sized blocks of characters.
template <typename Char>
@@ -8799,25 +9278,29 @@ class StringComparator {
explicit inline State(ConsStringIteratorOp* op)
: op_(op), is_one_byte_(true), length_(0), buffer8_(NULL) {}
- inline void Init(String* string, unsigned len) {
- op_->Reset();
- int32_t type = string->map()->instance_type();
- String::Visit(string, 0, *this, *op_, type, len);
+ inline void Init(String* string) {
+ ConsString* cons_string = String::VisitFlat(this, string);
+ op_->Reset(cons_string);
+ if (cons_string != NULL) {
+ int offset;
+ string = op_->Next(&offset);
+ String::VisitFlat(this, string, offset);
+ }
}
- inline void VisitOneByteString(const uint8_t* chars, unsigned length) {
+ inline void VisitOneByteString(const uint8_t* chars, int length) {
is_one_byte_ = true;
buffer8_ = chars;
length_ = length;
}
- inline void VisitTwoByteString(const uint16_t* chars, unsigned length) {
+ inline void VisitTwoByteString(const uint16_t* chars, int length) {
is_one_byte_ = false;
buffer16_ = chars;
length_ = length;
}
- void Advance(unsigned consumed) {
+ void Advance(int consumed) {
ASSERT(consumed <= length_);
// Still in buffer.
if (length_ != consumed) {
@@ -8830,18 +9313,16 @@ class StringComparator {
return;
}
// Advance state.
- ASSERT(op_->HasMore());
- int32_t type = 0;
- unsigned length = 0;
- String* next = op_->ContinueOperation(&type, &length);
+ int offset;
+ String* next = op_->Next(&offset);
+ ASSERT_EQ(0, offset);
ASSERT(next != NULL);
- ConsStringNullOp null_op;
- String::Visit(next, 0, *this, null_op, type, length);
+ String::VisitFlat(this, next);
}
ConsStringIteratorOp* const op_;
bool is_one_byte_;
- unsigned length_;
+ int length_;
union {
const uint8_t* buffer8_;
const uint16_t* buffer16_;
@@ -8859,18 +9340,18 @@ class StringComparator {
}
template<typename Chars1, typename Chars2>
- static inline bool Equals(State* state_1, State* state_2, unsigned to_check) {
+ static inline bool Equals(State* state_1, State* state_2, int to_check) {
const Chars1* a = reinterpret_cast<const Chars1*>(state_1->buffer8_);
const Chars2* b = reinterpret_cast<const Chars2*>(state_2->buffer8_);
return RawStringComparator<Chars1, Chars2>::compare(a, b, to_check);
}
- bool Equals(unsigned length, String* string_1, String* string_2) {
- ASSERT(length != 0);
- state_1_.Init(string_1, length);
- state_2_.Init(string_2, length);
+ bool Equals(String* string_1, String* string_2) {
+ int length = string_1->length();
+ state_1_.Init(string_1);
+ state_2_.Init(string_2);
while (true) {
- unsigned to_check = Min(state_1_.length_, state_2_.length_);
+ int to_check = Min(state_1_.length_, state_2_.length_);
ASSERT(to_check > 0 && to_check <= length);
bool is_equal;
if (state_1_.is_one_byte_) {
@@ -8904,6 +9385,7 @@ class StringComparator {
bool String::SlowEquals(String* other) {
+ DisallowHeapAllocation no_gc;
// Fast check: negative check with lengths.
int len = length();
if (len != other->length()) return false;
@@ -8933,14 +9415,9 @@ bool String::SlowEquals(String* other) {
// before we try to flatten the strings.
if (this->Get(0) != other->Get(0)) return false;
- String* lhs = this->TryFlattenGetString();
- String* rhs = other->TryFlattenGetString();
-
- // TODO(dcarney): Compare all types of flat strings with a Visitor.
- if (StringShape(lhs).IsSequentialAscii() &&
- StringShape(rhs).IsSequentialAscii()) {
- const uint8_t* str1 = SeqOneByteString::cast(lhs)->GetChars();
- const uint8_t* str2 = SeqOneByteString::cast(rhs)->GetChars();
+ if (IsSeqOneByteString() && other->IsSeqOneByteString()) {
+ const uint8_t* str1 = SeqOneByteString::cast(this)->GetChars();
+ const uint8_t* str2 = SeqOneByteString::cast(other)->GetChars();
return CompareRawStringContents(str1, str2, len);
}
@@ -8948,7 +9425,57 @@ bool String::SlowEquals(String* other) {
StringComparator comparator(isolate->objects_string_compare_iterator_a(),
isolate->objects_string_compare_iterator_b());
- return comparator.Equals(static_cast<unsigned>(len), lhs, rhs);
+ return comparator.Equals(this, other);
+}
+
+
+bool String::SlowEquals(Handle<String> one, Handle<String> two) {
+ // Fast check: negative check with lengths.
+ int one_length = one->length();
+ if (one_length != two->length()) return false;
+ if (one_length == 0) return true;
+
+ // Fast check: if hash code is computed for both strings
+ // a fast negative check can be performed.
+ if (one->HasHashCode() && two->HasHashCode()) {
+#ifdef ENABLE_SLOW_ASSERTS
+ if (FLAG_enable_slow_asserts) {
+ if (one->Hash() != two->Hash()) {
+ bool found_difference = false;
+ for (int i = 0; i < one_length; i++) {
+ if (one->Get(i) != two->Get(i)) {
+ found_difference = true;
+ break;
+ }
+ }
+ ASSERT(found_difference);
+ }
+ }
+#endif
+ if (one->Hash() != two->Hash()) return false;
+ }
+
+ // We know the strings are both non-empty. Compare the first chars
+ // before we try to flatten the strings.
+ if (one->Get(0) != two->Get(0)) return false;
+
+ one = String::Flatten(one);
+ two = String::Flatten(two);
+
+ DisallowHeapAllocation no_gc;
+ String::FlatContent flat1 = one->GetFlatContent();
+ String::FlatContent flat2 = two->GetFlatContent();
+
+ if (flat1.IsAscii() && flat2.IsAscii()) {
+ return CompareRawStringContents(flat1.ToOneByteVector().start(),
+ flat2.ToOneByteVector().start(),
+ one_length);
+ } else {
+ for (int i = 0; i < one_length; i++) {
+ if (flat1.Get(i) != flat2.Get(i)) return false;
+ }
+ return true;
+ }
}
@@ -9033,49 +9560,31 @@ bool String::IsTwoByteEqualTo(Vector<const uc16> str) {
class IteratingStringHasher: public StringHasher {
public:
static inline uint32_t Hash(String* string, uint32_t seed) {
- const unsigned len = static_cast<unsigned>(string->length());
- IteratingStringHasher hasher(len, seed);
- if (hasher.has_trivial_hash()) {
- return hasher.GetHashField();
- }
- int32_t type = string->map()->instance_type();
- ConsStringNullOp null_op;
- String::Visit(string, 0, hasher, null_op, type, len);
- // Flat strings terminate immediately.
- if (hasher.consumed_ == len) {
- ASSERT(!string->IsConsString());
- return hasher.GetHashField();
- }
- ASSERT(string->IsConsString());
+ IteratingStringHasher hasher(string->length(), seed);
+ // Nothing to do.
+ if (hasher.has_trivial_hash()) return hasher.GetHashField();
+ ConsString* cons_string = String::VisitFlat(&hasher, string);
+ // The string was flat.
+ if (cons_string == NULL) return hasher.GetHashField();
// This is a ConsString, iterate across it.
- ConsStringIteratorOp op;
- unsigned offset = 0;
- unsigned leaf_length = len;
- string = op.Operate(string, &offset, &type, &leaf_length);
- while (true) {
- ASSERT(hasher.consumed_ < len);
- String::Visit(string, 0, hasher, null_op, type, leaf_length);
- if (hasher.consumed_ == len) break;
- string = op.ContinueOperation(&type, &leaf_length);
- // This should be taken care of by the length check.
- ASSERT(string != NULL);
+ ConsStringIteratorOp op(cons_string);
+ int offset;
+ while (NULL != (string = op.Next(&offset))) {
+ String::VisitFlat(&hasher, string, offset);
}
return hasher.GetHashField();
}
- inline void VisitOneByteString(const uint8_t* chars, unsigned length) {
- AddCharacters(chars, static_cast<int>(length));
- consumed_ += length;
+ inline void VisitOneByteString(const uint8_t* chars, int length) {
+ AddCharacters(chars, length);
}
- inline void VisitTwoByteString(const uint16_t* chars, unsigned length) {
- AddCharacters(chars, static_cast<int>(length));
- consumed_ += length;
+ inline void VisitTwoByteString(const uint16_t* chars, int length) {
+ AddCharacters(chars, length);
}
private:
inline IteratingStringHasher(int len, uint32_t seed)
- : StringHasher(len, seed),
- consumed_(0) {}
- unsigned consumed_;
+ : StringHasher(len, seed) {
+ }
DISALLOW_COPY_AND_ASSIGN(IteratingStringHasher);
};
@@ -9156,7 +9665,6 @@ Handle<String> SeqString::Truncate(Handle<SeqString> string, int new_length) {
}
int delta = old_size - new_size;
- string->set_length(new_length);
Address start_of_string = string->address();
ASSERT_OBJECT_ALIGNED(start_of_string);
@@ -9175,6 +9683,10 @@ Handle<String> SeqString::Truncate(Handle<SeqString> string, int new_length) {
}
heap->AdjustLiveBytes(start_of_string, -delta, Heap::FROM_MUTATOR);
+ // We are storing the new length using release store after creating a filler
+ // for the left-over space to avoid races with the sweeper thread.
+ string->synchronized_set_length(new_length);
+
if (new_length == 0) return heap->isolate()->factory()->empty_string();
return string;
}
@@ -9368,11 +9880,16 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
}
}
+ // Note that we never eliminate a transition array, though we might right-trim
+ // such that number_of_transitions() == 0. If this assumption changes,
+ // TransitionArray::CopyInsert() will need to deal with the case that a
+ // transition array disappeared during GC.
int trim = t->number_of_transitions() - transition_index;
if (trim > 0) {
RightTrimFixedArray<Heap::FROM_GC>(heap, t, t->IsSimpleTransition()
? trim : trim * TransitionArray::kTransitionSize);
}
+ ASSERT(HasTransitionArray());
}
@@ -9493,52 +10010,38 @@ void SharedFunctionInfo::AddToOptimizedCodeMap(
Handle<Code> code,
Handle<FixedArray> literals,
BailoutId osr_ast_id) {
- CALL_HEAP_FUNCTION_VOID(
- shared->GetIsolate(),
- shared->AddToOptimizedCodeMap(
- *native_context, *code, *literals, osr_ast_id));
-}
-
-
-MaybeObject* SharedFunctionInfo::AddToOptimizedCodeMap(Context* native_context,
- Code* code,
- FixedArray* literals,
- BailoutId osr_ast_id) {
+ Isolate* isolate = shared->GetIsolate();
ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
ASSERT(native_context->IsNativeContext());
STATIC_ASSERT(kEntryLength == 4);
- Heap* heap = GetHeap();
- FixedArray* new_code_map;
- Object* value = optimized_code_map();
- Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt());
+ Handle<FixedArray> new_code_map;
+ Handle<Object> value(shared->optimized_code_map(), isolate);
+ int old_length;
if (value->IsSmi()) {
// No optimized code map.
- ASSERT_EQ(0, Smi::cast(value)->value());
+ ASSERT_EQ(0, Smi::cast(*value)->value());
// Create 3 entries per context {context, code, literals}.
- MaybeObject* maybe = heap->AllocateFixedArray(kInitialLength);
- if (!maybe->To(&new_code_map)) return maybe;
- new_code_map->set(kEntriesStart + kContextOffset, native_context);
- new_code_map->set(kEntriesStart + kCachedCodeOffset, code);
- new_code_map->set(kEntriesStart + kLiteralsOffset, literals);
- new_code_map->set(kEntriesStart + kOsrAstIdOffset, osr_ast_id_smi);
+ new_code_map = isolate->factory()->NewFixedArray(kInitialLength);
+ old_length = kEntriesStart;
} else {
// Copy old map and append one new entry.
- FixedArray* old_code_map = FixedArray::cast(value);
- ASSERT_EQ(-1, SearchOptimizedCodeMap(native_context, osr_ast_id));
- int old_length = old_code_map->length();
- int new_length = old_length + kEntryLength;
- MaybeObject* maybe = old_code_map->CopySize(new_length);
- if (!maybe->To(&new_code_map)) return maybe;
- new_code_map->set(old_length + kContextOffset, native_context);
- new_code_map->set(old_length + kCachedCodeOffset, code);
- new_code_map->set(old_length + kLiteralsOffset, literals);
- new_code_map->set(old_length + kOsrAstIdOffset, osr_ast_id_smi);
+ Handle<FixedArray> old_code_map = Handle<FixedArray>::cast(value);
+ ASSERT_EQ(-1, shared->SearchOptimizedCodeMap(*native_context, osr_ast_id));
+ old_length = old_code_map->length();
+ new_code_map = FixedArray::CopySize(
+ old_code_map, old_length + kEntryLength);
// Zap the old map for the sake of the heap verifier.
if (Heap::ShouldZapGarbage()) {
Object** data = old_code_map->data_start();
- MemsetPointer(data, heap->the_hole_value(), old_length);
+ MemsetPointer(data, isolate->heap()->the_hole_value(), old_length);
}
}
+ new_code_map->set(old_length + kContextOffset, *native_context);
+ new_code_map->set(old_length + kCachedCodeOffset, *code);
+ new_code_map->set(old_length + kLiteralsOffset, *literals);
+ new_code_map->set(old_length + kOsrAstIdOffset,
+ Smi::FromInt(osr_ast_id.ToInt()));
+
#ifdef DEBUG
for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
ASSERT(new_code_map->get(i + kContextOffset)->IsNativeContext());
@@ -9549,8 +10052,7 @@ MaybeObject* SharedFunctionInfo::AddToOptimizedCodeMap(Context* native_context,
ASSERT(new_code_map->get(i + kOsrAstIdOffset)->IsSmi());
}
#endif
- set_optimized_code_map(new_code_map);
- return new_code_map;
+ shared->set_optimized_code_map(*new_code_map);
}
@@ -9592,6 +10094,7 @@ void SharedFunctionInfo::ClearOptimizedCodeMap() {
void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code,
const char* reason) {
+ DisallowHeapAllocation no_gc;
if (optimized_code_map()->IsSmi()) return;
FixedArray* code_map = FixedArray::cast(optimized_code_map());
@@ -9657,48 +10160,37 @@ void JSObject::OptimizeAsPrototype(Handle<JSObject> object) {
}
-static MUST_USE_RESULT MaybeObject* CacheInitialJSArrayMaps(
- Context* native_context, Map* initial_map) {
+Handle<Object> CacheInitialJSArrayMaps(
+ Handle<Context> native_context, Handle<Map> initial_map) {
// Replace all of the cached initial array maps in the native context with
// the appropriate transitioned elements kind maps.
- Heap* heap = native_context->GetHeap();
- MaybeObject* maybe_maps =
- heap->AllocateFixedArrayWithHoles(kElementsKindCount, TENURED);
- FixedArray* maps;
- if (!maybe_maps->To(&maps)) return maybe_maps;
+ Factory* factory = native_context->GetIsolate()->factory();
+ Handle<FixedArray> maps = factory->NewFixedArrayWithHoles(
+ kElementsKindCount, TENURED);
- Map* current_map = initial_map;
+ Handle<Map> current_map = initial_map;
ElementsKind kind = current_map->elements_kind();
ASSERT(kind == GetInitialFastElementsKind());
- maps->set(kind, current_map);
+ maps->set(kind, *current_map);
for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
i < kFastElementsKindCount; ++i) {
- Map* new_map;
+ Handle<Map> new_map;
ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
if (current_map->HasElementsTransition()) {
- new_map = current_map->elements_transition_map();
+ new_map = handle(current_map->elements_transition_map());
ASSERT(new_map->elements_kind() == next_kind);
} else {
- MaybeObject* maybe_new_map =
- current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION);
- if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+ new_map = Map::CopyAsElementsKind(
+ current_map, next_kind, INSERT_TRANSITION);
}
- maps->set(next_kind, new_map);
+ maps->set(next_kind, *new_map);
current_map = new_map;
}
- native_context->set_js_array_maps(maps);
+ native_context->set_js_array_maps(*maps);
return initial_map;
}
-Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context,
- Handle<Map> initial_map) {
- CALL_HEAP_FUNCTION(native_context->GetIsolate(),
- CacheInitialJSArrayMaps(*native_context, *initial_map),
- Object);
-}
-
-
void JSFunction::SetInstancePrototype(Handle<JSFunction> function,
Handle<Object> value) {
ASSERT(value->IsJSReceiver());
@@ -9772,20 +10264,25 @@ void JSFunction::SetPrototype(Handle<JSFunction> function,
}
-void JSFunction::RemovePrototype() {
+bool JSFunction::RemovePrototype() {
Context* native_context = context()->native_context();
Map* no_prototype_map = shared()->strict_mode() == SLOPPY
? native_context->sloppy_function_without_prototype_map()
: native_context->strict_function_without_prototype_map();
- if (map() == no_prototype_map) return;
+ if (map() == no_prototype_map) return true;
- ASSERT(map() == (shared()->strict_mode() == SLOPPY
+#ifdef DEBUG
+ if (map() != (shared()->strict_mode() == SLOPPY
? native_context->sloppy_function_map()
- : native_context->strict_function_map()));
+ : native_context->strict_function_map())) {
+ return false;
+ }
+#endif
set_map(no_prototype_map);
set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value());
+ return true;
}
@@ -9883,20 +10380,171 @@ bool JSFunction::PassesFilter(const char* raw_filter) {
}
-MaybeObject* Oddball::Initialize(Heap* heap,
- const char* to_string,
- Object* to_number,
- byte kind) {
- String* internalized_to_string;
- { MaybeObject* maybe_string =
- heap->InternalizeUtf8String(
- CStrVector(to_string));
- if (!maybe_string->To(&internalized_to_string)) return maybe_string;
+void Oddball::Initialize(Isolate* isolate,
+ Handle<Oddball> oddball,
+ const char* to_string,
+ Handle<Object> to_number,
+ byte kind) {
+ Handle<String> internalized_to_string =
+ isolate->factory()->InternalizeUtf8String(to_string);
+ oddball->set_to_string(*internalized_to_string);
+ oddball->set_to_number(*to_number);
+ oddball->set_kind(kind);
+}
+
+
+void Script::InitLineEnds(Handle<Script> script) {
+ if (!script->line_ends()->IsUndefined()) return;
+
+ Isolate* isolate = script->GetIsolate();
+
+ if (!script->source()->IsString()) {
+ ASSERT(script->source()->IsUndefined());
+ Handle<FixedArray> empty = isolate->factory()->NewFixedArray(0);
+ script->set_line_ends(*empty);
+ ASSERT(script->line_ends()->IsFixedArray());
+ return;
+ }
+
+ Handle<String> src(String::cast(script->source()), isolate);
+
+ Handle<FixedArray> array = String::CalculateLineEnds(src, true);
+
+ if (*array != isolate->heap()->empty_fixed_array()) {
+ array->set_map(isolate->heap()->fixed_cow_array_map());
+ }
+
+ script->set_line_ends(*array);
+ ASSERT(script->line_ends()->IsFixedArray());
+}
+
+
+int Script::GetColumnNumber(Handle<Script> script, int code_pos) {
+ int line_number = GetLineNumber(script, code_pos);
+ if (line_number == -1) return -1;
+
+ DisallowHeapAllocation no_allocation;
+ FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
+ line_number = line_number - script->line_offset()->value();
+ if (line_number == 0) return code_pos + script->column_offset()->value();
+ int prev_line_end_pos =
+ Smi::cast(line_ends_array->get(line_number - 1))->value();
+ return code_pos - (prev_line_end_pos + 1);
+}
+
+
+int Script::GetLineNumberWithArray(int code_pos) {
+ DisallowHeapAllocation no_allocation;
+ ASSERT(line_ends()->IsFixedArray());
+ FixedArray* line_ends_array = FixedArray::cast(line_ends());
+ int line_ends_len = line_ends_array->length();
+ if (line_ends_len == 0) return -1;
+
+ if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos) {
+ return line_offset()->value();
+ }
+
+ int left = 0;
+ int right = line_ends_len;
+ while (int half = (right - left) / 2) {
+ if ((Smi::cast(line_ends_array->get(left + half)))->value() > code_pos) {
+ right -= half;
+ } else {
+ left += half;
+ }
}
- set_to_string(internalized_to_string);
- set_to_number(to_number);
- set_kind(kind);
- return this;
+ return right + line_offset()->value();
+}
+
+
+int Script::GetLineNumber(Handle<Script> script, int code_pos) {
+ InitLineEnds(script);
+ return script->GetLineNumberWithArray(code_pos);
+}
+
+
+int Script::GetLineNumber(int code_pos) {
+ DisallowHeapAllocation no_allocation;
+ if (!line_ends()->IsUndefined()) return GetLineNumberWithArray(code_pos);
+
+ // Slow mode: we do not have line_ends. We have to iterate through source.
+ if (!source()->IsString()) return -1;
+
+ String* source_string = String::cast(source());
+ int line = 0;
+ int len = source_string->length();
+ for (int pos = 0; pos < len; pos++) {
+ if (pos == code_pos) break;
+ if (source_string->Get(pos) == '\n') line++;
+ }
+ return line;
+}
+
+
+Handle<Object> Script::GetNameOrSourceURL(Handle<Script> script) {
+ Isolate* isolate = script->GetIsolate();
+ Handle<String> name_or_source_url_key =
+ isolate->factory()->InternalizeOneByteString(
+ STATIC_ASCII_VECTOR("nameOrSourceURL"));
+ Handle<JSObject> script_wrapper = Script::GetWrapper(script);
+ Handle<Object> property = Object::GetProperty(
+ script_wrapper, name_or_source_url_key).ToHandleChecked();
+ ASSERT(property->IsJSFunction());
+ Handle<JSFunction> method = Handle<JSFunction>::cast(property);
+ Handle<Object> result;
+ // Do not check against pending exception, since this function may be called
+ // when an exception has already been pending.
+ if (!Execution::TryCall(method, script_wrapper, 0, NULL).ToHandle(&result)) {
+ return isolate->factory()->undefined_value();
+ }
+ return result;
+}
+
+
+// Wrappers for scripts are kept alive and cached in weak global
+// handles referred from foreign objects held by the scripts as long as
+// they are used. When they are not used anymore, the garbage
+// collector will call the weak callback on the global handle
+// associated with the wrapper and get rid of both the wrapper and the
+// handle.
+static void ClearWrapperCache(
+ const v8::WeakCallbackData<v8::Value, void>& data) {
+ Object** location = reinterpret_cast<Object**>(data.GetParameter());
+ JSValue* wrapper = JSValue::cast(*location);
+ Foreign* foreign = Script::cast(wrapper->value())->wrapper();
+ ASSERT_EQ(foreign->foreign_address(), reinterpret_cast<Address>(location));
+ foreign->set_foreign_address(0);
+ GlobalHandles::Destroy(location);
+ Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate());
+ isolate->counters()->script_wrappers()->Decrement();
+}
+
+
+Handle<JSObject> Script::GetWrapper(Handle<Script> script) {
+ if (script->wrapper()->foreign_address() != NULL) {
+ // Return a handle for the existing script wrapper from the cache.
+ return Handle<JSValue>(
+ *reinterpret_cast<JSValue**>(script->wrapper()->foreign_address()));
+ }
+ Isolate* isolate = script->GetIsolate();
+ // Construct a new script wrapper.
+ isolate->counters()->script_wrappers()->Increment();
+ Handle<JSFunction> constructor = isolate->script_function();
+ Handle<JSValue> result =
+ Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
+
+ result->set_value(*script);
+
+ // Create a new weak global handle and use it to cache the wrapper
+ // for future use. The cache will automatically be cleared by the
+ // garbage collector when it is not used anymore.
+ Handle<Object> handle = isolate->global_handles()->Create(*result);
+ GlobalHandles::MakeWeak(handle.location(),
+ reinterpret_cast<void*>(handle.location()),
+ &ClearWrapperCache);
+ script->wrapper()->set_foreign_address(
+ reinterpret_cast<Address>(handle.location()));
+ return result;
}
@@ -10073,7 +10721,8 @@ void SharedFunctionInfo::StartInobjectSlackTracking(Map* map) {
set_live_objects_may_exist(true);
// No tracking during the snapshot construction phase.
- if (Serializer::enabled()) return;
+ Isolate* isolate = GetIsolate();
+ if (Serializer::enabled(isolate)) return;
if (map->unused_property_fields() == 0) return;
@@ -10083,7 +10732,7 @@ void SharedFunctionInfo::StartInobjectSlackTracking(Map* map) {
set_construction_count(kGenerousAllocationCount);
}
set_initial_map(map);
- Builtins* builtins = map->GetHeap()->isolate()->builtins();
+ Builtins* builtins = isolate->builtins();
ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubGeneric),
construct_stub());
set_construct_stub(builtins->builtin(Builtins::kJSConstructStubCountdown));
@@ -10132,6 +10781,9 @@ void SharedFunctionInfo::AttachInitialMap(Map* map) {
void SharedFunctionInfo::ResetForNewContext(int new_ic_age) {
code()->ClearInlineCaches();
+ // If we clear ICs, we need to clear the type feedback vector too, since
+ // CallICs are synced with a feedback vector slot.
+ ClearTypeFeedbackInfo();
set_ic_age(new_ic_age);
if (code()->kind() == Code::FUNCTION) {
code()->set_profiler_ticks(0);
@@ -10192,6 +10844,7 @@ void SharedFunctionInfo::CompleteInobjectSlackTracking() {
int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context,
BailoutId osr_ast_id) {
+ DisallowHeapAllocation no_gc;
ASSERT(native_context->IsNativeContext());
if (!FLAG_cache_optimized_code) return -1;
Object* value = optimized_code_map();
@@ -10500,21 +11153,6 @@ void Code::FindAllMaps(MapHandleList* maps) {
}
-void Code::FindAllTypes(TypeHandleList* types) {
- ASSERT(is_inline_cache_stub());
- DisallowHeapAllocation no_allocation;
- int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
- for (RelocIterator it(this, mask); !it.done(); it.next()) {
- RelocInfo* info = it.rinfo();
- Object* object = info->target_object();
- if (object->IsMap()) {
- Handle<Map> map(Map::cast(object));
- types->Add(IC::MapToType<HeapType>(map, map->GetIsolate()));
- }
- }
-}
-
-
Code* Code::FindFirstHandler() {
ASSERT(is_inline_cache_stub());
DisallowHeapAllocation no_allocation;
@@ -10587,19 +11225,16 @@ void Code::ClearInlineCaches(Code::Kind* kind) {
}
-void Code::ClearTypeFeedbackInfo(Heap* heap) {
- if (kind() != FUNCTION) return;
- Object* raw_info = type_feedback_info();
- if (raw_info->IsTypeFeedbackInfo()) {
- FixedArray* feedback_vector =
- TypeFeedbackInfo::cast(raw_info)->feedback_vector();
- for (int i = 0; i < feedback_vector->length(); i++) {
- Object* obj = feedback_vector->get(i);
- if (!obj->IsAllocationSite()) {
- // TODO(mvstanton): Can't I avoid a write barrier for this sentinel?
- feedback_vector->set(i,
- TypeFeedbackInfo::RawUninitializedSentinel(heap));
- }
+void SharedFunctionInfo::ClearTypeFeedbackInfo() {
+ FixedArray* vector = feedback_vector();
+ Heap* heap = GetHeap();
+ for (int i = 0; i < vector->length(); i++) {
+ Object* obj = vector->get(i);
+ if (!obj->IsAllocationSite()) {
+ vector->set(
+ i,
+ TypeFeedbackInfo::RawUninitializedSentinel(heap),
+ SKIP_WRITE_BARRIER);
}
}
}
@@ -10656,10 +11291,11 @@ void Code::MakeOlder(MarkingParity current_parity) {
if (sequence != NULL) {
Age age;
MarkingParity code_parity;
- GetCodeAgeAndParity(sequence, &age, &code_parity);
+ Isolate* isolate = GetIsolate();
+ GetCodeAgeAndParity(isolate, sequence, &age, &code_parity);
age = EffectiveAge(age);
if (age != kLastCodeAge && code_parity != current_parity) {
- PatchPlatformCodeAge(GetIsolate(),
+ PatchPlatformCodeAge(isolate,
sequence,
static_cast<Age>(age + 1),
current_parity);
@@ -10695,7 +11331,7 @@ Code::Age Code::GetRawAge() {
}
Age age;
MarkingParity parity;
- GetCodeAgeAndParity(sequence, &age, &parity);
+ GetCodeAgeAndParity(GetIsolate(), sequence, &age, &parity);
return age;
}
@@ -11180,8 +11816,8 @@ Handle<FixedArray> JSObject::SetFastElementsCapacityAndLength(
Handle<Map> new_map = (new_elements_kind != elements_kind)
? GetElementsTransitionMap(object, new_elements_kind)
: handle(object->map());
- object->ValidateElements();
- object->set_map_and_elements(*new_map, *new_elements);
+ JSObject::ValidateElements(object);
+ JSObject::SetMapAndElements(object, new_map, new_elements);
// Transition through the allocation site as well if present.
JSObject::UpdateAllocationSite(object, new_elements_kind);
@@ -11226,8 +11862,8 @@ void JSObject::SetFastDoubleElementsCapacityAndLength(Handle<JSObject> object,
ElementsAccessor* accessor = ElementsAccessor::ForKind(FAST_DOUBLE_ELEMENTS);
accessor->CopyElements(object, elems, elements_kind);
- object->ValidateElements();
- object->set_map_and_elements(*new_map, *elems);
+ JSObject::ValidateElements(object);
+ JSObject::SetMapAndElements(object, new_map, elems);
if (FLAG_trace_elements_transitions) {
PrintElementsTransition(stdout, object, elements_kind, old_elements,
@@ -11267,10 +11903,10 @@ static bool GetOldValue(Isolate* isolate,
ASSERT(attributes != ABSENT);
if (attributes == DONT_DELETE) return false;
Handle<Object> value;
- if (object->GetLocalElementAccessorPair(index) != NULL) {
+ if (!JSObject::GetLocalElementAccessorPair(object, index).is_null()) {
value = Handle<Object>::cast(isolate->factory()->the_hole_value());
} else {
- value = Object::GetElementNoExceptionThrown(isolate, object, index);
+ value = Object::GetElement(isolate, object, index).ToHandleChecked();
}
old_values->Add(value);
indices->Add(index);
@@ -11290,12 +11926,11 @@ static void EnqueueSpliceRecord(Handle<JSArray> object,
Handle<Object> args[] =
{ object, index_object, deleted, add_count_object };
- bool threw;
Execution::Call(isolate,
Handle<JSFunction>(isolate->observers_enqueue_splice()),
- isolate->factory()->undefined_value(), ARRAY_SIZE(args), args,
- &threw);
- ASSERT(!threw);
+ isolate->factory()->undefined_value(),
+ ARRAY_SIZE(args),
+ args).Assert();
}
@@ -11304,12 +11939,11 @@ static void BeginPerformSplice(Handle<JSArray> object) {
HandleScope scope(isolate);
Handle<Object> args[] = { object };
- bool threw;
Execution::Call(isolate,
Handle<JSFunction>(isolate->observers_begin_perform_splice()),
- isolate->factory()->undefined_value(), ARRAY_SIZE(args), args,
- &threw);
- ASSERT(!threw);
+ isolate->factory()->undefined_value(),
+ ARRAY_SIZE(args),
+ args).Assert();
}
@@ -11318,17 +11952,17 @@ static void EndPerformSplice(Handle<JSArray> object) {
HandleScope scope(isolate);
Handle<Object> args[] = { object };
- bool threw;
Execution::Call(isolate,
Handle<JSFunction>(isolate->observers_end_perform_splice()),
- isolate->factory()->undefined_value(), ARRAY_SIZE(args), args,
- &threw);
- ASSERT(!threw);
+ isolate->factory()->undefined_value(),
+ ARRAY_SIZE(args),
+ args).Assert();
}
-Handle<Object> JSArray::SetElementsLength(Handle<JSArray> array,
- Handle<Object> new_length_handle) {
+MaybeHandle<Object> JSArray::SetElementsLength(
+ Handle<JSArray> array,
+ Handle<Object> new_length_handle) {
// We should never end in here with a pixel or external array.
ASSERT(array->AllowsSetElementsLength());
if (!array->map()->is_observed()) {
@@ -11366,9 +12000,11 @@ Handle<Object> JSArray::SetElementsLength(Handle<JSArray> array,
}
}
- Handle<Object> hresult =
- array->GetElementsAccessor()->SetLength(array, new_length_handle);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, hresult, hresult);
+ Handle<Object> hresult;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, hresult,
+ array->GetElementsAccessor()->SetLength(array, new_length_handle),
+ Object);
CHECK(array->length()->ToArrayIndex(&new_length));
if (old_length == new_length) return hresult;
@@ -11398,13 +12034,13 @@ Handle<Object> JSArray::SetElementsLength(Handle<JSArray> array,
// Skip deletions where the property was an accessor, leaving holes
// in the array of old values.
if (old_values[i]->IsTheHole()) continue;
- JSObject::SetElement(deleted, indices[i] - index, old_values[i], NONE,
- SLOPPY);
+ JSObject::SetElement(
+ deleted, indices[i] - index, old_values[i], NONE, SLOPPY).Assert();
}
SetProperty(deleted, isolate->factory()->length_string(),
isolate->factory()->NewNumberFromUint(delete_count),
- NONE, SLOPPY);
+ NONE, SLOPPY).Assert();
}
EnqueueSpliceRecord(array, index, deleted, add_count);
@@ -11450,13 +12086,9 @@ Handle<Map> Map::PutPrototypeTransition(Handle<Map> map,
if (capacity > kMaxCachedPrototypeTransitions) return map;
// Grow array by factor 2 over and above what we need.
- Factory* factory = map->GetIsolate()->factory();
- cache = factory->CopySizeFixedArray(cache, transitions * 2 * step + header);
+ cache = FixedArray::CopySize(cache, transitions * 2 * step + header);
- CALL_AND_RETRY_OR_DIE(map->GetIsolate(),
- map->SetPrototypeTransitions(*cache),
- break,
- return Handle<Map>());
+ SetPrototypeTransitions(map, cache);
}
// Reload number of transitions as GC might shrink them.
@@ -11492,21 +12124,42 @@ void Map::ZapPrototypeTransitions() {
}
-void Map::AddDependentCompilationInfo(DependentCode::DependencyGroup group,
+// static
+void Map::AddDependentCompilationInfo(Handle<Map> map,
+ DependentCode::DependencyGroup group,
CompilationInfo* info) {
- Handle<DependentCode> dep(dependent_code());
Handle<DependentCode> codes =
- DependentCode::Insert(dep, group, info->object_wrapper());
- if (*codes != dependent_code()) set_dependent_code(*codes);
- info->dependencies(group)->Add(Handle<HeapObject>(this), info->zone());
+ DependentCode::Insert(handle(map->dependent_code(), info->isolate()),
+ group, info->object_wrapper());
+ if (*codes != map->dependent_code()) map->set_dependent_code(*codes);
+ info->dependencies(group)->Add(map, info->zone());
}
-void Map::AddDependentCode(DependentCode::DependencyGroup group,
+// static
+void Map::AddDependentCode(Handle<Map> map,
+ DependentCode::DependencyGroup group,
Handle<Code> code) {
Handle<DependentCode> codes = DependentCode::Insert(
- Handle<DependentCode>(dependent_code()), group, code);
- if (*codes != dependent_code()) set_dependent_code(*codes);
+ Handle<DependentCode>(map->dependent_code()), group, code);
+ if (*codes != map->dependent_code()) map->set_dependent_code(*codes);
+}
+
+
+// static
+void Map::AddDependentIC(Handle<Map> map,
+ Handle<Code> stub) {
+ ASSERT(stub->next_code_link()->IsUndefined());
+ int n = map->dependent_code()->number_of_entries(DependentCode::kWeakICGroup);
+ if (n == 0) {
+ // Slow path: insert the head of the list with possible heap allocation.
+ Map::AddDependentCode(map, DependentCode::kWeakICGroup, stub);
+ } else {
+ // Fast path: link the stub to the existing head of the list without any
+ // heap allocation.
+ ASSERT(n == 1);
+ map->dependent_code()->AddToDependentICList(stub);
+ }
}
@@ -11549,11 +12202,10 @@ Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries,
if (entries->object_at(i) == *object) return entries;
}
if (entries->length() < kCodesStartIndex + number_of_entries + 1) {
- Factory* factory = entries->GetIsolate()->factory();
int capacity = kCodesStartIndex + number_of_entries + 1;
if (capacity > 5) capacity = capacity * 5 / 4;
Handle<DependentCode> new_entries = Handle<DependentCode>::cast(
- factory->CopySizeFixedArray(entries, capacity, TENURED));
+ FixedArray::CopySize(entries, capacity, TENURED));
// The number of codes can change after GC.
starts.Recompute(*entries);
start = starts.at(group);
@@ -11640,10 +12292,22 @@ void DependentCode::RemoveCompilationInfo(DependentCode::DependencyGroup group,
}
+static bool CodeListContains(Object* head, Code* code) {
+ while (!head->IsUndefined()) {
+ if (head == code) return true;
+ head = Code::cast(head)->next_code_link();
+ }
+ return false;
+}
+
+
bool DependentCode::Contains(DependencyGroup group, Code* code) {
GroupStartIndexes starts(this);
int start = starts.at(group);
int end = starts.at(group + 1);
+ if (group == kWeakICGroup) {
+ return CodeListContains(object_at(start), code);
+ }
for (int i = start; i < end; i++) {
if (object_at(i) == code) return true;
}
@@ -11700,9 +12364,30 @@ void DependentCode::DeoptimizeDependentCodeGroup(
}
-Handle<Object> JSObject::SetPrototype(Handle<JSObject> object,
- Handle<Object> value,
- bool skip_hidden_prototypes) {
+void DependentCode::AddToDependentICList(Handle<Code> stub) {
+ DisallowHeapAllocation no_heap_allocation;
+ GroupStartIndexes starts(this);
+ int i = starts.at(kWeakICGroup);
+ stub->set_next_code_link(object_at(i));
+ set_object_at(i, *stub);
+}
+
+
+Handle<Map> Map::TransitionToPrototype(Handle<Map> map,
+ Handle<Object> prototype) {
+ Handle<Map> new_map = GetPrototypeTransition(map, prototype);
+ if (new_map.is_null()) {
+ new_map = Copy(map);
+ PutPrototypeTransition(map, prototype, new_map);
+ new_map->set_prototype(*prototype);
+ }
+ return new_map;
+}
+
+
+MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
+ Handle<Object> value,
+ bool skip_hidden_prototypes) {
#ifdef DEBUG
int size = object->Size();
#endif
@@ -11725,8 +12410,7 @@ Handle<Object> JSObject::SetPrototype(Handle<JSObject> object,
Handle<Object> args[] = { object };
Handle<Object> error = isolate->factory()->NewTypeError(
"non_extensible_proto", HandleVector(args, ARRAY_SIZE(args)));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
// Before we can set the prototype we need to be sure
@@ -11740,8 +12424,7 @@ Handle<Object> JSObject::SetPrototype(Handle<JSObject> object,
// Cycle detected.
Handle<Object> error = isolate->factory()->NewError(
"cyclic_proto", HandleVector<Object>(NULL, 0));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
}
@@ -11770,12 +12453,7 @@ Handle<Object> JSObject::SetPrototype(Handle<JSObject> object,
JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
}
- Handle<Map> new_map = Map::GetPrototypeTransition(map, value);
- if (new_map.is_null()) {
- new_map = Map::Copy(map);
- Map::PutPrototypeTransition(map, value, new_map);
- new_map->set_prototype(*value);
- }
+ Handle<Map> new_map = Map::TransitionToPrototype(map, value);
ASSERT(new_map->prototype() == *value);
JSObject::MigrateToMap(real_receiver, new_map);
@@ -11806,39 +12484,44 @@ void JSObject::EnsureCanContainElements(Handle<JSObject> object,
}
-AccessorPair* JSObject::GetLocalPropertyAccessorPair(Name* name) {
+MaybeHandle<AccessorPair> JSObject::GetLocalPropertyAccessorPair(
+ Handle<JSObject> object,
+ Handle<Name> name) {
uint32_t index = 0;
if (name->AsArrayIndex(&index)) {
- return GetLocalElementAccessorPair(index);
+ return GetLocalElementAccessorPair(object, index);
}
- LookupResult lookup(GetIsolate());
- LocalLookupRealNamedProperty(name, &lookup);
+ Isolate* isolate = object->GetIsolate();
+ LookupResult lookup(isolate);
+ object->LocalLookupRealNamedProperty(name, &lookup);
if (lookup.IsPropertyCallbacks() &&
lookup.GetCallbackObject()->IsAccessorPair()) {
- return AccessorPair::cast(lookup.GetCallbackObject());
+ return handle(AccessorPair::cast(lookup.GetCallbackObject()), isolate);
}
- return NULL;
+ return MaybeHandle<AccessorPair>();
}
-AccessorPair* JSObject::GetLocalElementAccessorPair(uint32_t index) {
- if (IsJSGlobalProxy()) {
- Object* proto = GetPrototype();
- if (proto->IsNull()) return NULL;
+MaybeHandle<AccessorPair> JSObject::GetLocalElementAccessorPair(
+ Handle<JSObject> object,
+ uint32_t index) {
+ if (object->IsJSGlobalProxy()) {
+ Handle<Object> proto(object->GetPrototype(), object->GetIsolate());
+ if (proto->IsNull()) return MaybeHandle<AccessorPair>();
ASSERT(proto->IsJSGlobalObject());
- return JSObject::cast(proto)->GetLocalElementAccessorPair(index);
+ return GetLocalElementAccessorPair(Handle<JSObject>::cast(proto), index);
}
// Check for lookup interceptor.
- if (HasIndexedInterceptor()) return NULL;
+ if (object->HasIndexedInterceptor()) return MaybeHandle<AccessorPair>();
- return GetElementsAccessor()->GetAccessorPair(this, this, index);
+ return object->GetElementsAccessor()->GetAccessorPair(object, object, index);
}
-Handle<Object> JSObject::SetElementWithInterceptor(
+MaybeHandle<Object> JSObject::SetElementWithInterceptor(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
@@ -11862,7 +12545,7 @@ Handle<Object> JSObject::SetElementWithInterceptor(
*object);
v8::Handle<v8::Value> result =
args.Call(setter, index, v8::Utils::ToLocal(value));
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (!result.IsEmpty()) return value;
}
@@ -11873,76 +12556,72 @@ Handle<Object> JSObject::SetElementWithInterceptor(
}
-MaybeObject* JSObject::GetElementWithCallback(Object* receiver,
- Object* structure,
- uint32_t index,
- Object* holder) {
- Isolate* isolate = GetIsolate();
+MaybeHandle<Object> JSObject::GetElementWithCallback(
+ Handle<JSObject> object,
+ Handle<Object> receiver,
+ Handle<Object> structure,
+ uint32_t index,
+ Handle<Object> holder) {
+ Isolate* isolate = object->GetIsolate();
ASSERT(!structure->IsForeign());
-
// api style callbacks.
if (structure->IsExecutableAccessorInfo()) {
- Handle<ExecutableAccessorInfo> data(
- ExecutableAccessorInfo::cast(structure));
+ Handle<ExecutableAccessorInfo> data =
+ Handle<ExecutableAccessorInfo>::cast(structure);
Object* fun_obj = data->getter();
v8::AccessorGetterCallback call_fun =
v8::ToCData<v8::AccessorGetterCallback>(fun_obj);
- if (call_fun == NULL) return isolate->heap()->undefined_value();
- HandleScope scope(isolate);
- Handle<JSObject> self(JSObject::cast(receiver));
- Handle<JSObject> holder_handle(JSObject::cast(holder));
+ if (call_fun == NULL) return isolate->factory()->undefined_value();
+ Handle<JSObject> holder_handle = Handle<JSObject>::cast(holder);
Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
Handle<String> key = isolate->factory()->NumberToString(number);
- LOG(isolate, ApiNamedPropertyAccess("load", *self, *key));
+ LOG(isolate, ApiNamedPropertyAccess("load", *holder_handle, *key));
PropertyCallbackArguments
- args(isolate, data->data(), *self, *holder_handle);
+ args(isolate, data->data(), *receiver, *holder_handle);
v8::Handle<v8::Value> result = args.Call(call_fun, v8::Utils::ToLocal(key));
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
- if (result.IsEmpty()) return isolate->heap()->undefined_value();
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ if (result.IsEmpty()) return isolate->factory()->undefined_value();
Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
result_internal->VerifyApiCallResultType();
- return *result_internal;
+ // Rebox handle before return.
+ return handle(*result_internal, isolate);
}
// __defineGetter__ callback
if (structure->IsAccessorPair()) {
- Object* getter = AccessorPair::cast(structure)->getter();
+ Handle<Object> getter(Handle<AccessorPair>::cast(structure)->getter(),
+ isolate);
if (getter->IsSpecFunction()) {
// TODO(rossberg): nicer would be to cast to some JSCallable here...
- return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter));
+ return GetPropertyWithDefinedGetter(
+ object, receiver, Handle<JSReceiver>::cast(getter));
}
// Getter is not a function.
- return isolate->heap()->undefined_value();
+ return isolate->factory()->undefined_value();
}
if (structure->IsDeclaredAccessorInfo()) {
- return GetDeclaredAccessorProperty(receiver,
- DeclaredAccessorInfo::cast(structure),
- isolate);
+ return GetDeclaredAccessorProperty(
+ receiver, Handle<DeclaredAccessorInfo>::cast(structure), isolate);
}
UNREACHABLE();
- return NULL;
+ return MaybeHandle<Object>();
}
-Handle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object,
- Handle<Object> structure,
- uint32_t index,
- Handle<Object> value,
- Handle<JSObject> holder,
- StrictMode strict_mode) {
+MaybeHandle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object,
+ Handle<Object> structure,
+ uint32_t index,
+ Handle<Object> value,
+ Handle<JSObject> holder,
+ StrictMode strict_mode) {
Isolate* isolate = object->GetIsolate();
// We should never get here to initialize a const with the hole
// value since a const declaration would conflict with the setter.
ASSERT(!value->IsTheHole());
-
- // To accommodate both the old and the new api we switch on the
- // data structure used to store the callbacks. Eventually foreign
- // callbacks should be phased out.
ASSERT(!structure->IsForeign());
-
if (structure->IsExecutableAccessorInfo()) {
// api style callbacks
Handle<ExecutableAccessorInfo> data =
@@ -11959,7 +12638,7 @@ Handle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object,
args.Call(call_fun,
v8::Utils::ToLocal(key),
v8::Utils::ToLocal(value));
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return value;
}
@@ -11975,8 +12654,7 @@ Handle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object,
Handle<Object> args[2] = { key, holder };
Handle<Object> error = isolate->factory()->NewTypeError(
"no_setter_in_callback", HandleVector(args, 2));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
}
@@ -11984,7 +12662,7 @@ Handle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object,
if (structure->IsDeclaredAccessorInfo()) return value;
UNREACHABLE();
- return Handle<Object>();
+ return MaybeHandle<Object>();
}
@@ -12015,11 +12693,11 @@ bool JSObject::HasDictionaryArgumentsElements() {
// Adding n elements in fast case is O(n*n).
// Note: revisit design to have dual undefined values to capture absent
// elements.
-Handle<Object> JSObject::SetFastElement(Handle<JSObject> object,
- uint32_t index,
- Handle<Object> value,
- StrictMode strict_mode,
- bool check_prototype) {
+MaybeHandle<Object> JSObject::SetFastElement(Handle<JSObject> object,
+ uint32_t index,
+ Handle<Object> value,
+ StrictMode strict_mode,
+ bool check_prototype) {
ASSERT(object->HasFastSmiOrObjectElements() ||
object->HasFastArgumentsElements());
@@ -12046,7 +12724,7 @@ Handle<Object> JSObject::SetFastElement(Handle<JSObject> object,
if (check_prototype &&
(index >= capacity || backing_store->get(index)->IsTheHole())) {
bool found;
- Handle<Object> result = SetElementWithCallbackSetterInPrototypes(
+ MaybeHandle<Object> result = SetElementWithCallbackSetterInPrototypes(
object, index, value, &found, strict_mode);
if (found) return result;
}
@@ -12105,7 +12783,7 @@ Handle<Object> JSObject::SetFastElement(Handle<JSObject> object,
SetFastDoubleElementsCapacityAndLength(object, new_capacity, array_length);
FixedDoubleArray::cast(object->elements())->set(index, value->Number());
- object->ValidateElements();
+ JSObject::ValidateElements(object);
return value;
}
// Change elements kind from Smi-only to generic FAST if necessary.
@@ -12129,7 +12807,7 @@ Handle<Object> JSObject::SetFastElement(Handle<JSObject> object,
SetFastElementsCapacityAndLength(object, new_capacity, array_length,
smi_mode);
new_elements->set(index, *value);
- object->ValidateElements();
+ JSObject::ValidateElements(object);
return value;
}
@@ -12143,13 +12821,14 @@ Handle<Object> JSObject::SetFastElement(Handle<JSObject> object,
}
-Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object,
- uint32_t index,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictMode strict_mode,
- bool check_prototype,
- SetPropertyMode set_mode) {
+MaybeHandle<Object> JSObject::SetDictionaryElement(
+ Handle<JSObject> object,
+ uint32_t index,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode,
+ bool check_prototype,
+ SetPropertyMode set_mode) {
ASSERT(object->HasDictionaryElements() ||
object->HasDictionaryArgumentsElements());
Isolate* isolate = object->GetIsolate();
@@ -12187,8 +12866,7 @@ Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object,
Handle<Object> error =
isolate->factory()->NewTypeError("strict_read_only_property",
HandleVector(args, 2));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
}
// Elements of the arguments object in slow mode might be slow aliases.
@@ -12209,8 +12887,8 @@ Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object,
// Can cause GC!
if (check_prototype) {
bool found;
- Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object,
- index, value, &found, strict_mode);
+ MaybeHandle<Object> result = SetElementWithCallbackSetterInPrototypes(
+ object, index, value, &found, strict_mode);
if (found) return result;
}
@@ -12226,8 +12904,7 @@ Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object,
Handle<Object> error =
isolate->factory()->NewTypeError("object_not_extensible",
HandleVector(args, 1));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
}
@@ -12275,7 +12952,7 @@ Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object,
SetFastElementsCapacityAndLength(object, new_length, new_length,
smi_mode);
}
- object->ValidateElements();
+ JSObject::ValidateElements(object);
#ifdef DEBUG
if (FLAG_trace_normalization) {
PrintF("Object elements are fast case again:\n");
@@ -12286,7 +12963,7 @@ Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object,
return value;
}
-Handle<Object> JSObject::SetFastDoubleElement(
+MaybeHandle<Object> JSObject::SetFastDoubleElement(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
@@ -12303,8 +12980,8 @@ Handle<Object> JSObject::SetFastDoubleElement(
(index >= elms_length ||
Handle<FixedDoubleArray>::cast(base_elms)->is_the_hole(index))) {
bool found;
- Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object,
- index, value, &found, strict_mode);
+ MaybeHandle<Object> result = SetElementWithCallbackSetterInPrototypes(
+ object, index, value, &found, strict_mode);
if (found) return result;
}
@@ -12323,11 +13000,12 @@ Handle<Object> JSObject::SetFastDoubleElement(
if (!value->IsNumber()) {
SetFastElementsCapacityAndLength(object, elms_length, length,
kDontAllowSmiElements);
- Handle<Object> result = SetFastElement(object, index, value, strict_mode,
- check_prototype);
- RETURN_IF_EMPTY_HANDLE_VALUE(object->GetIsolate(), result,
- Handle<Object>());
- object->ValidateElements();
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ object->GetIsolate(), result,
+ SetFastElement(object, index, value, strict_mode, check_prototype),
+ Object);
+ JSObject::ValidateElements(object);
return result;
}
@@ -12367,7 +13045,7 @@ Handle<Object> JSObject::SetFastDoubleElement(
ASSERT(static_cast<uint32_t>(new_capacity) > index);
SetFastDoubleElementsCapacityAndLength(object, new_capacity, index + 1);
FixedDoubleArray::cast(object->elements())->set(index, double_value);
- object->ValidateElements();
+ JSObject::ValidateElements(object);
return value;
}
}
@@ -12384,11 +13062,11 @@ Handle<Object> JSObject::SetFastDoubleElement(
}
-Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object,
- uint32_t index,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictMode strict_mode) {
+MaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object,
+ uint32_t index,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode) {
if (object->IsJSProxy()) {
return JSProxy::SetElementWithHandler(
Handle<JSProxy>::cast(object), object, index, value, strict_mode);
@@ -12398,40 +13076,38 @@ Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object,
}
-Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object,
- uint32_t index,
- Handle<Object> value,
- StrictMode strict_mode) {
+MaybeHandle<Object> JSObject::SetOwnElement(Handle<JSObject> object,
+ uint32_t index,
+ Handle<Object> value,
+ StrictMode strict_mode) {
ASSERT(!object->HasExternalArrayElements());
return JSObject::SetElement(object, index, value, NONE, strict_mode, false);
}
-Handle<Object> JSObject::SetElement(Handle<JSObject> object,
- uint32_t index,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictMode strict_mode,
- bool check_prototype,
- SetPropertyMode set_mode) {
+MaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object,
+ uint32_t index,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode,
+ bool check_prototype,
+ SetPropertyMode set_mode) {
Isolate* isolate = object->GetIsolate();
if (object->HasExternalArrayElements() ||
object->HasFixedTypedArrayElements()) {
if (!value->IsNumber() && !value->IsUndefined()) {
- bool has_exception;
- Handle<Object> number =
- Execution::ToNumber(isolate, value, &has_exception);
- if (has_exception) return Handle<Object>();
- value = number;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, value,
+ Execution::ToNumber(isolate, value), Object);
}
}
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_SET)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_SET)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return value;
}
}
@@ -12454,8 +13130,7 @@ Handle<Object> JSObject::SetElement(Handle<JSObject> object,
Handle<Object> args[] = { object, number };
Handle<Object> error = isolate->factory()->NewTypeError(
"redef_external_array_element", HandleVector(args, ARRAY_SIZE(args)));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
// Normalize the elements to enable attributes on the property.
@@ -12467,13 +13142,10 @@ Handle<Object> JSObject::SetElement(Handle<JSObject> object,
if (!object->map()->is_observed()) {
return object->HasIndexedInterceptor()
- ? SetElementWithInterceptor(object, index, value, attributes, strict_mode,
- check_prototype,
- set_mode)
+ ? SetElementWithInterceptor(object, index, value, attributes,
+ strict_mode, check_prototype, set_mode)
: SetElementWithoutInterceptor(object, index, value, attributes,
- strict_mode,
- check_prototype,
- set_mode);
+ strict_mode, check_prototype, set_mode);
}
PropertyAttributes old_attributes =
@@ -12483,8 +13155,8 @@ Handle<Object> JSObject::SetElement(Handle<JSObject> object,
Handle<Object> new_length_handle;
if (old_attributes != ABSENT) {
- if (object->GetLocalElementAccessorPair(index) == NULL) {
- old_value = Object::GetElementNoExceptionThrown(isolate, object, index);
+ if (GetLocalElementAccessorPair(object, index).is_null()) {
+ old_value = Object::GetElement(isolate, object, index).ToHandleChecked();
}
} else if (object->IsJSArray()) {
// Store old array length in case adding an element grows the array.
@@ -12493,15 +13165,17 @@ Handle<Object> JSObject::SetElement(Handle<JSObject> object,
}
// Check for lookup interceptor
- Handle<Object> result = object->HasIndexedInterceptor()
- ? SetElementWithInterceptor(object, index, value, attributes, strict_mode,
- check_prototype,
- set_mode)
- : SetElementWithoutInterceptor(object, index, value, attributes,
- strict_mode,
- check_prototype,
- set_mode);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>());
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ object->HasIndexedInterceptor()
+ ? SetElementWithInterceptor(
+ object, index, value, attributes,
+ strict_mode, check_prototype, set_mode)
+ : SetElementWithoutInterceptor(
+ object, index, value, attributes,
+ strict_mode, check_prototype, set_mode),
+ Object);
Handle<String> name = isolate->factory()->Uint32ToString(index);
PropertyAttributes new_attributes = GetLocalElementAttribute(object, index);
@@ -12531,7 +13205,7 @@ Handle<Object> JSObject::SetElement(Handle<JSObject> object,
EnqueueChangeRecord(object, "reconfigure", name, old_value);
} else {
Handle<Object> new_value =
- Object::GetElementNoExceptionThrown(isolate, object, index);
+ Object::GetElement(isolate, object, index).ToHandleChecked();
bool value_changed = !old_value->SameValue(*new_value);
if (old_attributes != new_attributes) {
if (!value_changed) old_value = isolate->factory()->the_hole_value();
@@ -12545,7 +13219,7 @@ Handle<Object> JSObject::SetElement(Handle<JSObject> object,
}
-Handle<Object> JSObject::SetElementWithoutInterceptor(
+MaybeHandle<Object> JSObject::SetElementWithoutInterceptor(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
@@ -12559,12 +13233,12 @@ Handle<Object> JSObject::SetElementWithoutInterceptor(
Isolate* isolate = object->GetIsolate();
if (FLAG_trace_external_array_abuse &&
IsExternalArrayElementsKind(object->GetElementsKind())) {
- CheckArrayAbuse(*object, "external elements write", index);
+ CheckArrayAbuse(object, "external elements write", index);
}
if (FLAG_trace_js_array_abuse &&
!IsExternalArrayElementsKind(object->GetElementsKind())) {
if (object->IsJSArray()) {
- CheckArrayAbuse(*object, "elements write", index, true);
+ CheckArrayAbuse(object, "elements write", index, true);
}
}
switch (object->GetElementsKind()) {
@@ -12744,30 +13418,9 @@ void JSObject::UpdateAllocationSite(Handle<JSObject> object,
Handle<AllocationSite> site;
{
DisallowHeapAllocation no_allocation;
- // Check if there is potentially a memento behind the object. If
- // the last word of the momento is on another page we return
- // immediatelly.
- Address object_address = object->address();
- Address memento_address = object_address + JSArray::kSize;
- Address last_memento_word_address = memento_address + kPointerSize;
- if (!NewSpacePage::OnSamePage(object_address,
- last_memento_word_address)) {
- return;
- }
-
- // Either object is the last object in the new space, or there is another
- // object of at least word size (the header map word) following it, so
- // suffices to compare ptr and top here.
- Address top = heap->NewSpaceTop();
- ASSERT(memento_address == top ||
- memento_address + HeapObject::kHeaderSize <= top);
- if (memento_address == top) return;
-
- HeapObject* candidate = HeapObject::FromAddress(memento_address);
- if (candidate->map() != heap->allocation_memento_map()) return;
- AllocationMemento* memento = AllocationMemento::cast(candidate);
- if (!memento->IsValid()) return;
+ AllocationMemento* memento = heap->FindAllocationMemento(*object);
+ if (memento == NULL) return;
// Walk through to the Allocation Site
site = handle(memento->GetAllocationSite());
@@ -12826,7 +13479,7 @@ void JSObject::TransitionElementsKind(Handle<JSObject> object,
if (IsFastSmiElementsKind(from_kind) &&
IsFastDoubleElementsKind(to_kind)) {
SetFastDoubleElementsCapacityAndLength(object, capacity, length);
- object->ValidateElements();
+ JSObject::ValidateElements(object);
return;
}
@@ -12834,7 +13487,7 @@ void JSObject::TransitionElementsKind(Handle<JSObject> object,
IsFastObjectElementsKind(to_kind)) {
SetFastElementsCapacityAndLength(object, capacity, length,
kDontAllowSmiElements);
- object->ValidateElements();
+ JSObject::ValidateElements(object);
return;
}
@@ -12861,32 +13514,22 @@ bool Map::IsValidElementsTransition(ElementsKind from_kind,
void JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray> array,
uint32_t index,
Handle<Object> value) {
- CALL_HEAP_FUNCTION_VOID(array->GetIsolate(),
- array->JSArrayUpdateLengthFromIndex(index, *value));
-}
-
-
-MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index,
- Object* value) {
uint32_t old_len = 0;
- CHECK(length()->ToArrayIndex(&old_len));
+ CHECK(array->length()->ToArrayIndex(&old_len));
// Check to see if we need to update the length. For now, we make
// sure that the length stays within 32-bits (unsigned).
if (index >= old_len && index != 0xffffffff) {
- Object* len;
- { MaybeObject* maybe_len =
- GetHeap()->NumberFromDouble(static_cast<double>(index) + 1);
- if (!maybe_len->ToObject(&len)) return maybe_len;
- }
- set_length(len);
+ Handle<Object> len = array->GetIsolate()->factory()->NewNumber(
+ static_cast<double>(index) + 1);
+ array->set_length(*len);
}
- return value;
}
-Handle<Object> JSObject::GetElementWithInterceptor(Handle<JSObject> object,
- Handle<Object> receiver,
- uint32_t index) {
+MaybeHandle<Object> JSObject::GetElementWithInterceptor(
+ Handle<JSObject> object,
+ Handle<Object> receiver,
+ uint32_t index) {
Isolate* isolate = object->GetIsolate();
// Make sure that the top context does not change when doing
@@ -12902,18 +13545,20 @@ Handle<Object> JSObject::GetElementWithInterceptor(Handle<JSObject> object,
PropertyCallbackArguments
args(isolate, interceptor->data(), *receiver, *object);
v8::Handle<v8::Value> result = args.Call(getter, index);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (!result.IsEmpty()) {
Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
result_internal->VerifyApiCallResultType();
// Rebox handle before return.
- return Handle<Object>(*result_internal, isolate);
+ return handle(*result_internal, isolate);
}
}
ElementsAccessor* handler = object->GetElementsAccessor();
- Handle<Object> result = handler->Get(receiver, object, index);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>());
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result, handler->Get(receiver, object, index),
+ Object);
if (!result->IsTheHole()) return result;
Handle<Object> proto(object->GetPrototype(), isolate);
@@ -13108,12 +13753,12 @@ bool JSObject::ShouldConvertToFastDoubleElements(
// together, so even though this function belongs in objects-debug.cc,
// we keep it here instead to satisfy certain compilers.
#ifdef OBJECT_PRINT
-template<typename Shape, typename Key>
-void Dictionary<Shape, Key>::Print(FILE* out) {
- int capacity = HashTable<Shape, Key>::Capacity();
+template<typename Derived, typename Shape, typename Key>
+void Dictionary<Derived, Shape, Key>::Print(FILE* out) {
+ int capacity = DerivedHashTable::Capacity();
for (int i = 0; i < capacity; i++) {
- Object* k = HashTable<Shape, Key>::KeyAt(i);
- if (HashTable<Shape, Key>::IsKey(k)) {
+ Object* k = DerivedHashTable::KeyAt(i);
+ if (DerivedHashTable::IsKey(k)) {
PrintF(out, " ");
if (k->IsString()) {
String::cast(k)->StringPrint(out);
@@ -13129,15 +13774,15 @@ void Dictionary<Shape, Key>::Print(FILE* out) {
#endif
-template<typename Shape, typename Key>
-void Dictionary<Shape, Key>::CopyValuesTo(FixedArray* elements) {
+template<typename Derived, typename Shape, typename Key>
+void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) {
int pos = 0;
- int capacity = HashTable<Shape, Key>::Capacity();
+ int capacity = DerivedHashTable::Capacity();
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
for (int i = 0; i < capacity; i++) {
- Object* k = Dictionary<Shape, Key>::KeyAt(i);
- if (Dictionary<Shape, Key>::IsKey(k)) {
+ Object* k = Dictionary::KeyAt(i);
+ if (Dictionary::IsKey(k)) {
elements->set(pos++, ValueAt(i), mode);
}
}
@@ -13165,7 +13810,7 @@ InterceptorInfo* JSObject::GetIndexedInterceptor() {
}
-Handle<Object> JSObject::GetPropertyPostInterceptor(
+MaybeHandle<Object> JSObject::GetPropertyPostInterceptor(
Handle<JSObject> object,
Handle<Object> receiver,
Handle<Name> name,
@@ -13173,36 +13818,20 @@ Handle<Object> JSObject::GetPropertyPostInterceptor(
// Check local property in holder, ignore interceptor.
Isolate* isolate = object->GetIsolate();
LookupResult lookup(isolate);
- object->LocalLookupRealNamedProperty(*name, &lookup);
- Handle<Object> result;
+ object->LocalLookupRealNamedProperty(name, &lookup);
if (lookup.IsFound()) {
- result = GetProperty(object, receiver, &lookup, name, attributes);
+ return GetProperty(object, receiver, &lookup, name, attributes);
} else {
// Continue searching via the prototype chain.
Handle<Object> prototype(object->GetPrototype(), isolate);
*attributes = ABSENT;
if (prototype->IsNull()) return isolate->factory()->undefined_value();
- result = GetPropertyWithReceiver(prototype, receiver, name, attributes);
- }
- return result;
-}
-
-
-MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
- Object* receiver,
- Name* name,
- PropertyAttributes* attributes) {
- // Check local property in holder, ignore interceptor.
- LookupResult result(GetIsolate());
- LocalLookupRealNamedProperty(name, &result);
- if (result.IsFound()) {
- return GetProperty(receiver, &result, name, attributes);
+ return GetPropertyWithReceiver(prototype, receiver, name, attributes);
}
- return GetHeap()->undefined_value();
}
-Handle<Object> JSObject::GetPropertyWithInterceptor(
+MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(
Handle<JSObject> object,
Handle<Object> receiver,
Handle<Name> name,
@@ -13224,12 +13853,12 @@ Handle<Object> JSObject::GetPropertyWithInterceptor(
args(isolate, interceptor->data(), *receiver, *object);
v8::Handle<v8::Value> result =
args.Call(getter, v8::Utils::ToLocal(name_string));
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (!result.IsEmpty()) {
*attributes = NONE;
Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
result_internal->VerifyApiCallResultType();
- // Rebox handle to escape this scope.
+ // Rebox handle before return.
return handle(*result_internal, isolate);
}
}
@@ -13238,20 +13867,72 @@ Handle<Object> JSObject::GetPropertyWithInterceptor(
}
+// Compute the property keys from the interceptor.
+// TODO(rossberg): support symbols in API, and filter here if needed.
+MaybeHandle<JSObject> JSObject::GetKeysForNamedInterceptor(
+ Handle<JSObject> object, Handle<JSReceiver> receiver) {
+ Isolate* isolate = receiver->GetIsolate();
+ Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
+ PropertyCallbackArguments
+ args(isolate, interceptor->data(), *receiver, *object);
+ v8::Handle<v8::Object> result;
+ if (!interceptor->enumerator()->IsUndefined()) {
+ v8::NamedPropertyEnumeratorCallback enum_fun =
+ v8::ToCData<v8::NamedPropertyEnumeratorCallback>(
+ interceptor->enumerator());
+ LOG(isolate, ApiObjectAccess("interceptor-named-enum", *object));
+ result = args.Call(enum_fun);
+ }
+ if (result.IsEmpty()) return MaybeHandle<JSObject>();
+#if ENABLE_EXTRA_CHECKS
+ CHECK(v8::Utils::OpenHandle(*result)->IsJSArray() ||
+ v8::Utils::OpenHandle(*result)->HasSloppyArgumentsElements());
+#endif
+ // Rebox before returning.
+ return handle(*v8::Utils::OpenHandle(*result), isolate);
+}
+
+
+// Compute the element keys from the interceptor.
+MaybeHandle<JSObject> JSObject::GetKeysForIndexedInterceptor(
+ Handle<JSObject> object, Handle<JSReceiver> receiver) {
+ Isolate* isolate = receiver->GetIsolate();
+ Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
+ PropertyCallbackArguments
+ args(isolate, interceptor->data(), *receiver, *object);
+ v8::Handle<v8::Object> result;
+ if (!interceptor->enumerator()->IsUndefined()) {
+ v8::IndexedPropertyEnumeratorCallback enum_fun =
+ v8::ToCData<v8::IndexedPropertyEnumeratorCallback>(
+ interceptor->enumerator());
+ LOG(isolate, ApiObjectAccess("interceptor-indexed-enum", *object));
+ result = args.Call(enum_fun);
+ }
+ if (result.IsEmpty()) return MaybeHandle<JSObject>();
+#if ENABLE_EXTRA_CHECKS
+ CHECK(v8::Utils::OpenHandle(*result)->IsJSArray() ||
+ v8::Utils::OpenHandle(*result)->HasSloppyArgumentsElements());
+#endif
+ // Rebox before returning.
+ return handle(*v8::Utils::OpenHandle(*result), isolate);
+}
+
+
bool JSObject::HasRealNamedProperty(Handle<JSObject> object,
Handle<Name> key) {
Isolate* isolate = object->GetIsolate();
SealHandleScope shs(isolate);
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayNamedAccessWrapper(object, key, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
+ if (!isolate->MayNamedAccess(object, key, v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
+ // TODO(yangguo): Issue 3269, check for scheduled exception missing?
return false;
}
}
LookupResult result(isolate);
- object->LocalLookupRealNamedProperty(*key, &result);
+ object->LocalLookupRealNamedProperty(key, &result);
return result.IsFound() && !result.IsInterceptor();
}
@@ -13261,8 +13942,9 @@ bool JSObject::HasRealElementProperty(Handle<JSObject> object, uint32_t index) {
HandleScope scope(isolate);
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
+ if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
+ // TODO(yangguo): Issue 3269, check for scheduled exception missing?
return false;
}
}
@@ -13286,14 +13968,15 @@ bool JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
SealHandleScope shs(isolate);
// Check access rights if needed.
if (object->IsAccessCheckNeeded()) {
- if (!isolate->MayNamedAccessWrapper(object, key, v8::ACCESS_HAS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_HAS);
+ if (!isolate->MayNamedAccess(object, key, v8::ACCESS_HAS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
+ // TODO(yangguo): Issue 3269, check for scheduled exception missing?
return false;
}
}
LookupResult result(isolate);
- object->LocalLookupRealNamedProperty(*key, &result);
+ object->LocalLookupRealNamedProperty(key, &result);
return result.IsPropertyCallbacks();
}
@@ -13630,8 +14313,8 @@ class StringKey : public HashTableKey {
// StringSharedKeys are used as keys in the eval cache.
class StringSharedKey : public HashTableKey {
public:
- StringSharedKey(String* source,
- SharedFunctionInfo* shared,
+ StringSharedKey(Handle<String> source,
+ Handle<SharedFunctionInfo> shared,
StrictMode strict_mode,
int scope_position)
: source_(source),
@@ -13639,11 +14322,12 @@ class StringSharedKey : public HashTableKey {
strict_mode_(strict_mode),
scope_position_(scope_position) { }
- bool IsMatch(Object* other) {
+ bool IsMatch(Object* other) V8_OVERRIDE {
+ DisallowHeapAllocation no_allocation;
if (!other->IsFixedArray()) return false;
FixedArray* other_array = FixedArray::cast(other);
SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
- if (shared != shared_) return false;
+ if (shared != *shared_) return false;
int strict_unchecked = Smi::cast(other_array->get(2))->value();
ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT);
StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked);
@@ -13651,7 +14335,7 @@ class StringSharedKey : public HashTableKey {
int scope_position = Smi::cast(other_array->get(3))->value();
if (scope_position != scope_position_) return false;
String* source = String::cast(other_array->get(1));
- return source->Equals(source_);
+ return source->Equals(*source_);
}
static uint32_t StringSharedHashHelper(String* source,
@@ -13665,7 +14349,7 @@ class StringSharedKey : public HashTableKey {
// script source code and the start position of the calling scope.
// We do this to ensure that the cache entries can survive garbage
// collection.
- Script* script = Script::cast(shared->script());
+ Script* script(Script::cast(shared->script()));
hash ^= String::cast(script->source())->Hash();
if (strict_mode == STRICT) hash ^= 0x8000;
hash += scope_position;
@@ -13673,12 +14357,13 @@ class StringSharedKey : public HashTableKey {
return hash;
}
- uint32_t Hash() {
- return StringSharedHashHelper(
- source_, shared_, strict_mode_, scope_position_);
+ uint32_t Hash() V8_OVERRIDE {
+ return StringSharedHashHelper(*source_, *shared_, strict_mode_,
+ scope_position_);
}
- uint32_t HashForObject(Object* obj) {
+ uint32_t HashForObject(Object* obj) V8_OVERRIDE {
+ DisallowHeapAllocation no_allocation;
FixedArray* other_array = FixedArray::cast(obj);
SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
String* source = String::cast(other_array->get(1));
@@ -13690,22 +14375,19 @@ class StringSharedKey : public HashTableKey {
source, shared, strict_mode, scope_position);
}
- MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) {
- Object* obj;
- { MaybeObject* maybe_obj = heap->AllocateFixedArray(4);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- FixedArray* other_array = FixedArray::cast(obj);
- other_array->set(0, shared_);
- other_array->set(1, source_);
- other_array->set(2, Smi::FromInt(strict_mode_));
- other_array->set(3, Smi::FromInt(scope_position_));
- return other_array;
+
+ Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE {
+ Handle<FixedArray> array = isolate->factory()->NewFixedArray(4);
+ array->set(0, *shared_);
+ array->set(1, *source_);
+ array->set(2, Smi::FromInt(strict_mode_));
+ array->set(3, Smi::FromInt(scope_position_));
+ return array;
}
private:
- String* source_;
- SharedFunctionInfo* shared_;
+ Handle<String> source_;
+ Handle<SharedFunctionInfo> shared_;
StrictMode strict_mode_;
int scope_position_;
};
@@ -13714,7 +14396,7 @@ class StringSharedKey : public HashTableKey {
// RegExpKey carries the source and flags of a regular expression as key.
class RegExpKey : public HashTableKey {
public:
- RegExpKey(String* string, JSRegExp::Flags flags)
+ RegExpKey(Handle<String> string, JSRegExp::Flags flags)
: string_(string),
flags_(Smi::FromInt(flags.value())) { }
@@ -13722,22 +14404,22 @@ class RegExpKey : public HashTableKey {
// stored value is stored where the key should be. IsMatch then
// compares the search key to the found object, rather than comparing
// a key to a key.
- bool IsMatch(Object* obj) {
+ bool IsMatch(Object* obj) V8_OVERRIDE {
FixedArray* val = FixedArray::cast(obj);
return string_->Equals(String::cast(val->get(JSRegExp::kSourceIndex)))
&& (flags_ == val->get(JSRegExp::kFlagsIndex));
}
- uint32_t Hash() { return RegExpHash(string_, flags_); }
+ uint32_t Hash() V8_OVERRIDE { return RegExpHash(*string_, flags_); }
- Object* AsObject(Heap* heap) {
+ Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE {
// Plain hash maps, which is where regexp keys are used, don't
// use this function.
UNREACHABLE();
- return NULL;
+ return MaybeHandle<Object>().ToHandleChecked();
}
- uint32_t HashForObject(Object* obj) {
+ uint32_t HashForObject(Object* obj) V8_OVERRIDE {
FixedArray* val = FixedArray::cast(obj);
return RegExpHash(String::cast(val->get(JSRegExp::kSourceIndex)),
Smi::cast(val->get(JSRegExp::kFlagsIndex)));
@@ -13747,20 +14429,20 @@ class RegExpKey : public HashTableKey {
return string->Hash() + flags->value();
}
- String* string_;
+ Handle<String> string_;
Smi* flags_;
};
-MaybeObject* OneByteStringKey::AsObject(Heap* heap) {
+Handle<Object> OneByteStringKey::AsHandle(Isolate* isolate) {
if (hash_field_ == 0) Hash();
- return heap->AllocateOneByteInternalizedString(string_, hash_field_);
+ return isolate->factory()->NewOneByteInternalizedString(string_, hash_field_);
}
-MaybeObject* TwoByteStringKey::AsObject(Heap* heap) {
+Handle<Object> TwoByteStringKey::AsHandle(Isolate* isolate) {
if (hash_field_ == 0) Hash();
- return heap->AllocateTwoByteInternalizedString(string_, hash_field_);
+ return isolate->factory()->NewTwoByteInternalizedString(string_, hash_field_);
}
@@ -13781,19 +14463,18 @@ const uint16_t* SubStringKey<uint16_t>::GetChars() {
template<>
-MaybeObject* SubStringKey<uint8_t>::AsObject(Heap* heap) {
+Handle<Object> SubStringKey<uint8_t>::AsHandle(Isolate* isolate) {
if (hash_field_ == 0) Hash();
Vector<const uint8_t> chars(GetChars() + from_, length_);
- return heap->AllocateOneByteInternalizedString(chars, hash_field_);
+ return isolate->factory()->NewOneByteInternalizedString(chars, hash_field_);
}
template<>
-MaybeObject* SubStringKey<uint16_t>::AsObject(
- Heap* heap) {
+Handle<Object> SubStringKey<uint16_t>::AsHandle(Isolate* isolate) {
if (hash_field_ == 0) Hash();
Vector<const uint16_t> chars(GetChars() + from_, length_);
- return heap->AllocateTwoByteInternalizedString(chars, hash_field_);
+ return isolate->factory()->NewTwoByteInternalizedString(chars, hash_field_);
}
@@ -13818,32 +14499,31 @@ template class SubStringKey<uint16_t>;
// InternalizedStringKey carries a string/internalized-string object as key.
class InternalizedStringKey : public HashTableKey {
public:
- explicit InternalizedStringKey(String* string)
+ explicit InternalizedStringKey(Handle<String> string)
: string_(string) { }
- bool IsMatch(Object* string) {
- return String::cast(string)->Equals(string_);
+ virtual bool IsMatch(Object* string) V8_OVERRIDE {
+ return String::cast(string)->Equals(*string_);
}
- uint32_t Hash() { return string_->Hash(); }
+ virtual uint32_t Hash() V8_OVERRIDE { return string_->Hash(); }
- uint32_t HashForObject(Object* other) {
+ virtual uint32_t HashForObject(Object* other) V8_OVERRIDE {
return String::cast(other)->Hash();
}
- MaybeObject* AsObject(Heap* heap) {
- // Attempt to flatten the string, so that internalized strings will most
- // often be flat strings.
- string_ = string_->TryFlattenGetString();
+ virtual Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE {
// Internalize the string if possible.
- Map* map = heap->InternalizedStringMapForString(string_);
- if (map != NULL) {
- string_->set_map_no_write_barrier(map);
+ MaybeHandle<Map> maybe_map =
+ isolate->factory()->InternalizedStringMapForString(string_);
+ Handle<Map> map;
+ if (maybe_map.ToHandle(&map)) {
+ string_->set_map_no_write_barrier(*map);
ASSERT(string_->IsInternalizedString());
return string_;
}
// Otherwise allocate a new internalized string.
- return heap->AllocateInternalizedStringImpl(
+ return isolate->factory()->NewInternalizedStringImpl(
string_, string_->length(), string_->hash_field());
}
@@ -13851,30 +14531,32 @@ class InternalizedStringKey : public HashTableKey {
return String::cast(obj)->Hash();
}
- String* string_;
+ Handle<String> string_;
};
-template<typename Shape, typename Key>
-void HashTable<Shape, Key>::IteratePrefix(ObjectVisitor* v) {
+template<typename Derived, typename Shape, typename Key>
+void HashTable<Derived, Shape, Key>::IteratePrefix(ObjectVisitor* v) {
IteratePointers(v, 0, kElementsStartOffset);
}
-template<typename Shape, typename Key>
-void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) {
+template<typename Derived, typename Shape, typename Key>
+void HashTable<Derived, Shape, Key>::IterateElements(ObjectVisitor* v) {
IteratePointers(v,
kElementsStartOffset,
kHeaderSize + length() * kPointerSize);
}
-template<typename Shape, typename Key>
-MaybeObject* HashTable<Shape, Key>::Allocate(Heap* heap,
- int at_least_space_for,
- MinimumCapacity capacity_option,
- PretenureFlag pretenure) {
- ASSERT(!capacity_option || IS_POWER_OF_TWO(at_least_space_for));
+template<typename Derived, typename Shape, typename Key>
+Handle<Derived> HashTable<Derived, Shape, Key>::New(
+ Isolate* isolate,
+ int at_least_space_for,
+ MinimumCapacity capacity_option,
+ PretenureFlag pretenure) {
+ ASSERT(0 <= at_least_space_for);
+ ASSERT(!capacity_option || IsPowerOf2(at_least_space_for));
int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY)
? at_least_space_for
: ComputeCapacity(at_least_space_for);
@@ -13882,22 +14564,23 @@ MaybeObject* HashTable<Shape, Key>::Allocate(Heap* heap,
v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true);
}
- Object* obj;
- { MaybeObject* maybe_obj =
- heap-> AllocateHashTable(EntryToIndex(capacity), pretenure);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- HashTable::cast(obj)->SetNumberOfElements(0);
- HashTable::cast(obj)->SetNumberOfDeletedElements(0);
- HashTable::cast(obj)->SetCapacity(capacity);
- return obj;
+ Factory* factory = isolate->factory();
+ int length = EntryToIndex(capacity);
+ Handle<FixedArray> array = factory->NewFixedArray(length, pretenure);
+ array->set_map_no_write_barrier(*factory->hash_table_map());
+ Handle<Derived> table = Handle<Derived>::cast(array);
+
+ table->SetNumberOfElements(0);
+ table->SetNumberOfDeletedElements(0);
+ table->SetCapacity(capacity);
+ return table;
}
// Find entry for key otherwise return kNotFound.
-int NameDictionary::FindEntry(Name* key) {
+int NameDictionary::FindEntry(Handle<Name> key) {
if (!key->IsUniqueName()) {
- return HashTable<NameDictionaryShape, Name*>::FindEntry(key);
+ return DerivedHashTable::FindEntry(key);
}
// Optimized for unique names. Knowledge of the key type allows:
@@ -13918,24 +14601,26 @@ int NameDictionary::FindEntry(Name* key) {
int index = EntryToIndex(entry);
Object* element = get(index);
if (element->IsUndefined()) break; // Empty entry.
- if (key == element) return entry;
+ if (*key == element) return entry;
if (!element->IsUniqueName() &&
!element->IsTheHole() &&
- Name::cast(element)->Equals(key)) {
+ Name::cast(element)->Equals(*key)) {
// Replace a key that is a non-internalized string by the equivalent
// internalized string for faster further lookups.
- set(index, key);
+ set(index, *key);
return entry;
}
- ASSERT(element->IsTheHole() || !Name::cast(element)->Equals(key));
+ ASSERT(element->IsTheHole() || !Name::cast(element)->Equals(*key));
entry = NextProbe(entry, count++, capacity);
}
return kNotFound;
}
-template<typename Shape, typename Key>
-MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) {
+template<typename Derived, typename Shape, typename Key>
+void HashTable<Derived, Shape, Key>::Rehash(
+ Handle<Derived> new_table,
+ Key key) {
ASSERT(NumberOfElements() < new_table->Capacity());
DisallowHeapAllocation no_gc;
@@ -13954,7 +14639,7 @@ MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) {
uint32_t from_index = EntryToIndex(i);
Object* k = get(from_index);
if (IsKey(k)) {
- uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k);
+ uint32_t hash = HashTable::HashForObject(key, k);
uint32_t insertion_index =
EntryToIndex(new_table->FindInsertionEntry(hash));
for (int j = 0; j < Shape::kEntrySize; j++) {
@@ -13964,16 +14649,16 @@ MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) {
}
new_table->SetNumberOfElements(NumberOfElements());
new_table->SetNumberOfDeletedElements(0);
- return new_table;
}
-template<typename Shape, typename Key>
-uint32_t HashTable<Shape, Key>::EntryForProbe(Key key,
- Object* k,
- int probe,
- uint32_t expected) {
- uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k);
+template<typename Derived, typename Shape, typename Key>
+uint32_t HashTable<Derived, Shape, Key>::EntryForProbe(
+ Key key,
+ Object* k,
+ int probe,
+ uint32_t expected) {
+ uint32_t hash = HashTable::HashForObject(key, k);
uint32_t capacity = Capacity();
uint32_t entry = FirstProbe(hash, capacity);
for (int i = 1; i < probe; i++) {
@@ -13984,10 +14669,10 @@ uint32_t HashTable<Shape, Key>::EntryForProbe(Key key,
}
-template<typename Shape, typename Key>
-void HashTable<Shape, Key>::Swap(uint32_t entry1,
- uint32_t entry2,
- WriteBarrierMode mode) {
+template<typename Derived, typename Shape, typename Key>
+void HashTable<Derived, Shape, Key>::Swap(uint32_t entry1,
+ uint32_t entry2,
+ WriteBarrierMode mode) {
int index1 = EntryToIndex(entry1);
int index2 = EntryToIndex(entry2);
Object* temp[Shape::kEntrySize];
@@ -14003,8 +14688,8 @@ void HashTable<Shape, Key>::Swap(uint32_t entry1,
}
-template<typename Shape, typename Key>
-void HashTable<Shape, Key>::Rehash(Key key) {
+template<typename Derived, typename Shape, typename Key>
+void HashTable<Derived, Shape, Key>::Rehash(Key key) {
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = GetWriteBarrierMode(no_gc);
uint32_t capacity = Capacity();
@@ -14036,71 +14721,73 @@ void HashTable<Shape, Key>::Rehash(Key key) {
}
-template<typename Shape, typename Key>
-MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n,
- Key key,
- PretenureFlag pretenure) {
- int capacity = Capacity();
- int nof = NumberOfElements() + n;
- int nod = NumberOfDeletedElements();
+template<typename Derived, typename Shape, typename Key>
+Handle<Derived> HashTable<Derived, Shape, Key>::EnsureCapacity(
+ Handle<Derived> table,
+ int n,
+ Key key,
+ PretenureFlag pretenure) {
+ Isolate* isolate = table->GetIsolate();
+ int capacity = table->Capacity();
+ int nof = table->NumberOfElements() + n;
+ int nod = table->NumberOfDeletedElements();
// Return if:
// 50% is still free after adding n elements and
// at most 50% of the free elements are deleted elements.
if (nod <= (capacity - nof) >> 1) {
int needed_free = nof >> 1;
- if (nof + needed_free <= capacity) return this;
+ if (nof + needed_free <= capacity) return table;
}
const int kMinCapacityForPretenure = 256;
bool should_pretenure = pretenure == TENURED ||
- ((capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this));
- Object* obj;
- { MaybeObject* maybe_obj =
- Allocate(GetHeap(),
- nof * 2,
- USE_DEFAULT_MINIMUM_CAPACITY,
- should_pretenure ? TENURED : NOT_TENURED);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
+ ((capacity > kMinCapacityForPretenure) &&
+ !isolate->heap()->InNewSpace(*table));
+ Handle<Derived> new_table = HashTable::New(
+ isolate,
+ nof * 2,
+ USE_DEFAULT_MINIMUM_CAPACITY,
+ should_pretenure ? TENURED : NOT_TENURED);
- return Rehash(HashTable::cast(obj), key);
+ table->Rehash(new_table, key);
+ return new_table;
}
-template<typename Shape, typename Key>
-MaybeObject* HashTable<Shape, Key>::Shrink(Key key) {
- int capacity = Capacity();
- int nof = NumberOfElements();
+template<typename Derived, typename Shape, typename Key>
+Handle<Derived> HashTable<Derived, Shape, Key>::Shrink(Handle<Derived> table,
+ Key key) {
+ int capacity = table->Capacity();
+ int nof = table->NumberOfElements();
// Shrink to fit the number of elements if only a quarter of the
// capacity is filled with elements.
- if (nof > (capacity >> 2)) return this;
+ if (nof > (capacity >> 2)) return table;
// Allocate a new dictionary with room for at least the current
// number of elements. The allocation method will make sure that
// there is extra room in the dictionary for additions. Don't go
// lower than room for 16 elements.
int at_least_room_for = nof;
- if (at_least_room_for < 16) return this;
+ if (at_least_room_for < 16) return table;
+ Isolate* isolate = table->GetIsolate();
const int kMinCapacityForPretenure = 256;
bool pretenure =
(at_least_room_for > kMinCapacityForPretenure) &&
- !GetHeap()->InNewSpace(this);
- Object* obj;
- { MaybeObject* maybe_obj =
- Allocate(GetHeap(),
- at_least_room_for,
- USE_DEFAULT_MINIMUM_CAPACITY,
- pretenure ? TENURED : NOT_TENURED);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
+ !isolate->heap()->InNewSpace(*table);
+ Handle<Derived> new_table = HashTable::New(
+ isolate,
+ at_least_room_for,
+ USE_DEFAULT_MINIMUM_CAPACITY,
+ pretenure ? TENURED : NOT_TENURED);
- return Rehash(HashTable::cast(obj), key);
+ table->Rehash(new_table, key);
+ return new_table;
}
-template<typename Shape, typename Key>
-uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) {
+template<typename Derived, typename Shape, typename Key>
+uint32_t HashTable<Derived, Shape, Key>::FindInsertionEntry(uint32_t hash) {
uint32_t capacity = Capacity();
uint32_t entry = FirstProbe(hash, capacity);
uint32_t count = 1;
@@ -14117,221 +14804,238 @@ uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) {
// Force instantiation of template instances class.
// Please note this list is compiler dependent.
-template class HashTable<StringTableShape, HashTableKey*>;
+template class HashTable<StringTable, StringTableShape, HashTableKey*>;
-template class HashTable<CompilationCacheShape, HashTableKey*>;
+template class HashTable<CompilationCacheTable,
+ CompilationCacheShape,
+ HashTableKey*>;
-template class HashTable<MapCacheShape, HashTableKey*>;
+template class HashTable<MapCache, MapCacheShape, HashTableKey*>;
-template class HashTable<ObjectHashTableShape<1>, Object*>;
+template class HashTable<ObjectHashTable,
+ ObjectHashTableShape,
+ Handle<Object> >;
-template class HashTable<ObjectHashTableShape<2>, Object*>;
+template class HashTable<WeakHashTable, WeakHashTableShape<2>, Handle<Object> >;
-template class HashTable<WeakHashTableShape<2>, Object*>;
+template class Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >;
-template class Dictionary<NameDictionaryShape, Name*>;
+template class Dictionary<SeededNumberDictionary,
+ SeededNumberDictionaryShape,
+ uint32_t>;
-template class Dictionary<SeededNumberDictionaryShape, uint32_t>;
+template class Dictionary<UnseededNumberDictionary,
+ UnseededNumberDictionaryShape,
+ uint32_t>;
-template class Dictionary<UnseededNumberDictionaryShape, uint32_t>;
+template Handle<SeededNumberDictionary>
+Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
+ New(Isolate*, int at_least_space_for, PretenureFlag pretenure);
-template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::
- Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure);
+template Handle<UnseededNumberDictionary>
+Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
+ New(Isolate*, int at_least_space_for, PretenureFlag pretenure);
-template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
- Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure);
+template Handle<NameDictionary>
+Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
+ New(Isolate*, int n, PretenureFlag pretenure);
-template MaybeObject* Dictionary<NameDictionaryShape, Name*>::
- Allocate(Heap* heap, int n, PretenureFlag pretenure);
+template Handle<SeededNumberDictionary>
+Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
+ AtPut(Handle<SeededNumberDictionary>, uint32_t, Handle<Object>);
-template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::AtPut(
- uint32_t, Object*);
+template Handle<UnseededNumberDictionary>
+Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
+ AtPut(Handle<UnseededNumberDictionary>, uint32_t, Handle<Object>);
-template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
- AtPut(uint32_t, Object*);
-
-template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>::
+template Object*
+Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
SlowReverseLookup(Object* value);
-template Object* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
+template Object*
+Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
SlowReverseLookup(Object* value);
-template Object* Dictionary<NameDictionaryShape, Name*>::SlowReverseLookup(
- Object*);
-
-template void Dictionary<SeededNumberDictionaryShape, uint32_t>::CopyKeysTo(
- FixedArray*,
- PropertyAttributes,
- Dictionary<SeededNumberDictionaryShape, uint32_t>::SortMode);
-
-template Object* Dictionary<NameDictionaryShape, Name*>::DeleteProperty(
- int, JSObject::DeleteMode);
-
-template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>::
- DeleteProperty(int, JSObject::DeleteMode);
-
-template MaybeObject* Dictionary<NameDictionaryShape, Name*>::Shrink(Name* n);
-
-template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink(
- uint32_t);
+template Object*
+Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
+ SlowReverseLookup(Object* value);
-template void Dictionary<NameDictionaryShape, Name*>::CopyKeysTo(
- FixedArray*,
- int,
- PropertyAttributes,
- Dictionary<NameDictionaryShape, Name*>::SortMode);
+template void
+Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
+ CopyKeysTo(
+ FixedArray*,
+ PropertyAttributes,
+ Dictionary<SeededNumberDictionary,
+ SeededNumberDictionaryShape,
+ uint32_t>::SortMode);
+
+template Handle<Object>
+Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::DeleteProperty(
+ Handle<NameDictionary>, int, JSObject::DeleteMode);
+
+template Handle<Object>
+Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
+ DeleteProperty(Handle<SeededNumberDictionary>, int, JSObject::DeleteMode);
+
+template Handle<NameDictionary>
+HashTable<NameDictionary, NameDictionaryShape, Handle<Name> >::
+ New(Isolate*, int, MinimumCapacity, PretenureFlag);
+
+template Handle<NameDictionary>
+HashTable<NameDictionary, NameDictionaryShape, Handle<Name> >::
+ Shrink(Handle<NameDictionary>, Handle<Name>);
+
+template Handle<SeededNumberDictionary>
+HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
+ Shrink(Handle<SeededNumberDictionary>, uint32_t);
+
+template void Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
+ CopyKeysTo(
+ FixedArray*,
+ int,
+ PropertyAttributes,
+ Dictionary<
+ NameDictionary, NameDictionaryShape, Handle<Name> >::SortMode);
template int
-Dictionary<NameDictionaryShape, Name*>::NumberOfElementsFilterAttributes(
- PropertyAttributes);
+Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
+ NumberOfElementsFilterAttributes(PropertyAttributes);
-template MaybeObject* Dictionary<NameDictionaryShape, Name*>::Add(
- Name*, Object*, PropertyDetails);
+template Handle<NameDictionary>
+Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::Add(
+ Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails);
-template MaybeObject*
-Dictionary<NameDictionaryShape, Name*>::GenerateNewEnumerationIndices();
+template void
+Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
+ GenerateNewEnumerationIndices(Handle<NameDictionary>);
template int
-Dictionary<SeededNumberDictionaryShape, uint32_t>::
+Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
NumberOfElementsFilterAttributes(PropertyAttributes);
-template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Add(
- uint32_t, Object*, PropertyDetails);
-
-template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::Add(
- uint32_t, Object*, PropertyDetails);
+template Handle<SeededNumberDictionary>
+Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
+ Add(Handle<SeededNumberDictionary>,
+ uint32_t,
+ Handle<Object>,
+ PropertyDetails);
-template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::
- EnsureCapacity(int, uint32_t);
+template Handle<UnseededNumberDictionary>
+Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
+ Add(Handle<UnseededNumberDictionary>,
+ uint32_t,
+ Handle<Object>,
+ PropertyDetails);
-template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
- EnsureCapacity(int, uint32_t);
+template Handle<SeededNumberDictionary>
+Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
+ EnsureCapacity(Handle<SeededNumberDictionary>, int, uint32_t);
-template MaybeObject* Dictionary<NameDictionaryShape, Name*>::
- EnsureCapacity(int, Name*);
+template Handle<UnseededNumberDictionary>
+Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
+ EnsureCapacity(Handle<UnseededNumberDictionary>, int, uint32_t);
-template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::
- AddEntry(uint32_t, Object*, PropertyDetails, uint32_t);
-
-template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
- AddEntry(uint32_t, Object*, PropertyDetails, uint32_t);
-
-template MaybeObject* Dictionary<NameDictionaryShape, Name*>::AddEntry(
- Name*, Object*, PropertyDetails, uint32_t);
+template Handle<NameDictionary>
+Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
+ EnsureCapacity(Handle<NameDictionary>, int, Handle<Name>);
template
-int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements();
+int Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
+ NumberOfEnumElements();
template
-int Dictionary<NameDictionaryShape, Name*>::NumberOfEnumElements();
+int Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
+ NumberOfEnumElements();
template
-int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t);
+int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
+ FindEntry(uint32_t);
Handle<Object> JSObject::PrepareSlowElementsForSort(
Handle<JSObject> object, uint32_t limit) {
- CALL_HEAP_FUNCTION(object->GetIsolate(),
- object->PrepareSlowElementsForSort(limit),
- Object);
-}
-
-
-// Collates undefined and unexisting elements below limit from position
-// zero of the elements. The object stays in Dictionary mode.
-MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
- ASSERT(HasDictionaryElements());
+ ASSERT(object->HasDictionaryElements());
+ Isolate* isolate = object->GetIsolate();
// Must stay in dictionary mode, either because of requires_slow_elements,
// or because we are not going to sort (and therefore compact) all of the
// elements.
- SeededNumberDictionary* dict = element_dictionary();
- HeapNumber* result_double = NULL;
- if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
- // Allocate space for result before we start mutating the object.
- Object* new_double;
- { MaybeObject* maybe_new_double = GetHeap()->AllocateHeapNumber(0.0);
- if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double;
- }
- result_double = HeapNumber::cast(new_double);
- }
-
- Object* obj;
- { MaybeObject* maybe_obj =
- SeededNumberDictionary::Allocate(GetHeap(), dict->NumberOfElements());
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- SeededNumberDictionary* new_dict = SeededNumberDictionary::cast(obj);
-
- DisallowHeapAllocation no_alloc;
+ Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate);
+ Handle<SeededNumberDictionary> new_dict =
+ SeededNumberDictionary::New(isolate, dict->NumberOfElements());
uint32_t pos = 0;
uint32_t undefs = 0;
int capacity = dict->Capacity();
+ Handle<Smi> bailout(Smi::FromInt(-1), isolate);
+ // Entry to the new dictionary does not cause it to grow, as we have
+ // allocated one that is large enough for all entries.
+ DisallowHeapAllocation no_gc;
for (int i = 0; i < capacity; i++) {
Object* k = dict->KeyAt(i);
- if (dict->IsKey(k)) {
- ASSERT(k->IsNumber());
- ASSERT(!k->IsSmi() || Smi::cast(k)->value() >= 0);
- ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0);
- ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32);
- Object* value = dict->ValueAt(i);
- PropertyDetails details = dict->DetailsAt(i);
- if (details.type() == CALLBACKS || details.IsReadOnly()) {
- // Bail out and do the sorting of undefineds and array holes in JS.
- // Also bail out if the element is not supposed to be moved.
- return Smi::FromInt(-1);
- }
- uint32_t key = NumberToUint32(k);
- // In the following we assert that adding the entry to the new dictionary
- // does not cause GC. This is the case because we made sure to allocate
- // the dictionary big enough above, so it need not grow.
- if (key < limit) {
- if (value->IsUndefined()) {
- undefs++;
- } else {
- if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
- // Adding an entry with the key beyond smi-range requires
- // allocation. Bailout.
- return Smi::FromInt(-1);
- }
- new_dict->AddNumberEntry(pos, value, details)->ToObjectUnchecked();
- pos++;
- }
+ if (!dict->IsKey(k)) continue;
+
+ ASSERT(k->IsNumber());
+ ASSERT(!k->IsSmi() || Smi::cast(k)->value() >= 0);
+ ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0);
+ ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32);
+
+ HandleScope scope(isolate);
+ Handle<Object> value(dict->ValueAt(i), isolate);
+ PropertyDetails details = dict->DetailsAt(i);
+ if (details.type() == CALLBACKS || details.IsReadOnly()) {
+ // Bail out and do the sorting of undefineds and array holes in JS.
+ // Also bail out if the element is not supposed to be moved.
+ return bailout;
+ }
+
+ uint32_t key = NumberToUint32(k);
+ if (key < limit) {
+ if (value->IsUndefined()) {
+ undefs++;
+ } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
+ // Adding an entry with the key beyond smi-range requires
+ // allocation. Bailout.
+ return bailout;
} else {
- if (key > static_cast<uint32_t>(Smi::kMaxValue)) {
- // Adding an entry with the key beyond smi-range requires
- // allocation. Bailout.
- return Smi::FromInt(-1);
- }
- new_dict->AddNumberEntry(key, value, details)->ToObjectUnchecked();
+ Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
+ new_dict, pos, value, details);
+ ASSERT(result.is_identical_to(new_dict));
+ USE(result);
+ pos++;
}
+ } else if (key > static_cast<uint32_t>(Smi::kMaxValue)) {
+ // Adding an entry with the key beyond smi-range requires
+ // allocation. Bailout.
+ return bailout;
+ } else {
+ Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
+ new_dict, key, value, details);
+ ASSERT(result.is_identical_to(new_dict));
+ USE(result);
}
}
uint32_t result = pos;
PropertyDetails no_details = PropertyDetails(NONE, NORMAL, 0);
- Heap* heap = GetHeap();
while (undefs > 0) {
if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
// Adding an entry with the key beyond smi-range requires
// allocation. Bailout.
- return Smi::FromInt(-1);
+ return bailout;
}
- new_dict->AddNumberEntry(pos, heap->undefined_value(), no_details)->
- ToObjectUnchecked();
+ HandleScope scope(isolate);
+ Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
+ new_dict, pos, isolate->factory()->undefined_value(), no_details);
+ ASSERT(result.is_identical_to(new_dict));
+ USE(result);
pos++;
undefs--;
}
- set_elements(new_dict);
-
- if (result <= static_cast<uint32_t>(Smi::kMaxValue)) {
- return Smi::FromInt(static_cast<int>(result));
- }
+ object->set_elements(*new_dict);
- ASSERT_NE(NULL, result_double);
- result_double->set_value(static_cast<double>(result));
- return result_double;
+ AllowHeapAllocation allocate_return_value;
+ return isolate->factory()->NewNumberFromUint(result);
}
@@ -14365,9 +15069,9 @@ Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object,
Handle<FixedArray> fast_elements =
isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure);
dict->CopyValuesTo(*fast_elements);
- object->ValidateElements();
+ JSObject::ValidateElements(object);
- object->set_map_and_elements(*new_map, *fast_elements);
+ JSObject::SetMapAndElements(object, new_map, fast_elements);
} else if (object->HasExternalArrayElements() ||
object->HasFixedTypedArrayElements()) {
// Typed arrays cannot have holes or undefined elements.
@@ -14502,11 +15206,14 @@ size_t JSTypedArray::element_size() {
}
-Object* ExternalUint8ClampedArray::SetValue(uint32_t index, Object* value) {
+Handle<Object> ExternalUint8ClampedArray::SetValue(
+ Handle<ExternalUint8ClampedArray> array,
+ uint32_t index,
+ Handle<Object> value) {
uint8_t clamped_value = 0;
- if (index < static_cast<uint32_t>(length())) {
+ if (index < static_cast<uint32_t>(array->length())) {
if (value->IsSmi()) {
- int int_value = Smi::cast(value)->value();
+ int int_value = Handle<Smi>::cast(value)->value();
if (int_value < 0) {
clamped_value = 0;
} else if (int_value > 255) {
@@ -14515,7 +15222,7 @@ Object* ExternalUint8ClampedArray::SetValue(uint32_t index, Object* value) {
clamped_value = static_cast<uint8_t>(int_value);
}
} else if (value->IsHeapNumber()) {
- double double_value = HeapNumber::cast(value)->value();
+ double double_value = Handle<HeapNumber>::cast(value)->value();
if (!(double_value > 0)) {
// NaN and less than zero clamp to zero.
clamped_value = 0;
@@ -14531,32 +15238,25 @@ Object* ExternalUint8ClampedArray::SetValue(uint32_t index, Object* value) {
// converted to a number type further up in the call chain.
ASSERT(value->IsUndefined());
}
- set(index, clamped_value);
+ array->set(index, clamped_value);
}
- return Smi::FromInt(clamped_value);
+ return handle(Smi::FromInt(clamped_value), array->GetIsolate());
}
-Handle<Object> ExternalUint8ClampedArray::SetValue(
- Handle<ExternalUint8ClampedArray> array,
+template<typename ExternalArrayClass, typename ValueType>
+static Handle<Object> ExternalArrayIntSetter(
+ Isolate* isolate,
+ Handle<ExternalArrayClass> receiver,
uint32_t index,
Handle<Object> value) {
- return Handle<Object>(array->SetValue(index, *value), array->GetIsolate());
-}
-
-
-template<typename ExternalArrayClass, typename ValueType>
-static MaybeObject* ExternalArrayIntSetter(Heap* heap,
- ExternalArrayClass* receiver,
- uint32_t index,
- Object* value) {
ValueType cast_value = 0;
if (index < static_cast<uint32_t>(receiver->length())) {
if (value->IsSmi()) {
- int int_value = Smi::cast(value)->value();
+ int int_value = Handle<Smi>::cast(value)->value();
cast_value = static_cast<ValueType>(int_value);
} else if (value->IsHeapNumber()) {
- double double_value = HeapNumber::cast(value)->value();
+ double double_value = Handle<HeapNumber>::cast(value)->value();
cast_value = static_cast<ValueType>(DoubleToInt32(double_value));
} else {
// Clamp undefined to zero (default). All other types have been
@@ -14565,88 +15265,47 @@ static MaybeObject* ExternalArrayIntSetter(Heap* heap,
}
receiver->set(index, cast_value);
}
- return heap->NumberFromInt32(cast_value);
+ return isolate->factory()->NewNumberFromInt(cast_value);
}
Handle<Object> ExternalInt8Array::SetValue(Handle<ExternalInt8Array> array,
uint32_t index,
Handle<Object> value) {
- CALL_HEAP_FUNCTION(array->GetIsolate(),
- array->SetValue(index, *value),
- Object);
-}
-
-
-MaybeObject* ExternalInt8Array::SetValue(uint32_t index, Object* value) {
- return ExternalArrayIntSetter<ExternalInt8Array, int8_t>
- (GetHeap(), this, index, value);
+ return ExternalArrayIntSetter<ExternalInt8Array, int8_t>(
+ array->GetIsolate(), array, index, value);
}
-Handle<Object> ExternalUint8Array::SetValue(
- Handle<ExternalUint8Array> array,
- uint32_t index,
- Handle<Object> value) {
- CALL_HEAP_FUNCTION(array->GetIsolate(),
- array->SetValue(index, *value),
- Object);
+Handle<Object> ExternalUint8Array::SetValue(Handle<ExternalUint8Array> array,
+ uint32_t index,
+ Handle<Object> value) {
+ return ExternalArrayIntSetter<ExternalUint8Array, uint8_t>(
+ array->GetIsolate(), array, index, value);
}
-MaybeObject* ExternalUint8Array::SetValue(uint32_t index,
- Object* value) {
- return ExternalArrayIntSetter<ExternalUint8Array, uint8_t>
- (GetHeap(), this, index, value);
+Handle<Object> ExternalInt16Array::SetValue(Handle<ExternalInt16Array> array,
+ uint32_t index,
+ Handle<Object> value) {
+ return ExternalArrayIntSetter<ExternalInt16Array, int16_t>(
+ array->GetIsolate(), array, index, value);
}
-Handle<Object> ExternalInt16Array::SetValue(
- Handle<ExternalInt16Array> array,
- uint32_t index,
- Handle<Object> value) {
- CALL_HEAP_FUNCTION(array->GetIsolate(),
- array->SetValue(index, *value),
- Object);
-}
-
-
-MaybeObject* ExternalInt16Array::SetValue(uint32_t index,
- Object* value) {
- return ExternalArrayIntSetter<ExternalInt16Array, int16_t>
- (GetHeap(), this, index, value);
-}
-
-
-Handle<Object> ExternalUint16Array::SetValue(
- Handle<ExternalUint16Array> array,
- uint32_t index,
- Handle<Object> value) {
- CALL_HEAP_FUNCTION(array->GetIsolate(),
- array->SetValue(index, *value),
- Object);
-}
-
-
-MaybeObject* ExternalUint16Array::SetValue(uint32_t index,
- Object* value) {
- return ExternalArrayIntSetter<ExternalUint16Array, uint16_t>
- (GetHeap(), this, index, value);
+Handle<Object> ExternalUint16Array::SetValue(Handle<ExternalUint16Array> array,
+ uint32_t index,
+ Handle<Object> value) {
+ return ExternalArrayIntSetter<ExternalUint16Array, uint16_t>(
+ array->GetIsolate(), array, index, value);
}
Handle<Object> ExternalInt32Array::SetValue(Handle<ExternalInt32Array> array,
- uint32_t index,
- Handle<Object> value) {
- CALL_HEAP_FUNCTION(array->GetIsolate(),
- array->SetValue(index, *value),
- Object);
-}
-
-
-MaybeObject* ExternalInt32Array::SetValue(uint32_t index, Object* value) {
- return ExternalArrayIntSetter<ExternalInt32Array, int32_t>
- (GetHeap(), this, index, value);
+ uint32_t index,
+ Handle<Object> value) {
+ return ExternalArrayIntSetter<ExternalInt32Array, int32_t>(
+ array->GetIsolate(), array, index, value);
}
@@ -14654,30 +15313,22 @@ Handle<Object> ExternalUint32Array::SetValue(
Handle<ExternalUint32Array> array,
uint32_t index,
Handle<Object> value) {
- CALL_HEAP_FUNCTION(array->GetIsolate(),
- array->SetValue(index, *value),
- Object);
-}
-
-
-MaybeObject* ExternalUint32Array::SetValue(uint32_t index, Object* value) {
uint32_t cast_value = 0;
- Heap* heap = GetHeap();
- if (index < static_cast<uint32_t>(length())) {
+ if (index < static_cast<uint32_t>(array->length())) {
if (value->IsSmi()) {
- int int_value = Smi::cast(value)->value();
+ int int_value = Handle<Smi>::cast(value)->value();
cast_value = static_cast<uint32_t>(int_value);
} else if (value->IsHeapNumber()) {
- double double_value = HeapNumber::cast(value)->value();
+ double double_value = Handle<HeapNumber>::cast(value)->value();
cast_value = static_cast<uint32_t>(DoubleToUint32(double_value));
} else {
// Clamp undefined to zero (default). All other types have been
// converted to a number type further up in the call chain.
ASSERT(value->IsUndefined());
}
- set(index, cast_value);
+ array->set(index, cast_value);
}
- return heap->NumberFromUint32(cast_value);
+ return array->GetIsolate()->factory()->NewNumberFromUint(cast_value);
}
@@ -14685,30 +15336,22 @@ Handle<Object> ExternalFloat32Array::SetValue(
Handle<ExternalFloat32Array> array,
uint32_t index,
Handle<Object> value) {
- CALL_HEAP_FUNCTION(array->GetIsolate(),
- array->SetValue(index, *value),
- Object);
-}
-
-
-MaybeObject* ExternalFloat32Array::SetValue(uint32_t index, Object* value) {
float cast_value = static_cast<float>(OS::nan_value());
- Heap* heap = GetHeap();
- if (index < static_cast<uint32_t>(length())) {
+ if (index < static_cast<uint32_t>(array->length())) {
if (value->IsSmi()) {
- int int_value = Smi::cast(value)->value();
+ int int_value = Handle<Smi>::cast(value)->value();
cast_value = static_cast<float>(int_value);
} else if (value->IsHeapNumber()) {
- double double_value = HeapNumber::cast(value)->value();
+ double double_value = Handle<HeapNumber>::cast(value)->value();
cast_value = static_cast<float>(double_value);
} else {
// Clamp undefined to NaN (default). All other types have been
// converted to a number type further up in the call chain.
ASSERT(value->IsUndefined());
}
- set(index, cast_value);
+ array->set(index, cast_value);
}
- return heap->AllocateHeapNumber(cast_value);
+ return array->GetIsolate()->factory()->NewNumber(cast_value);
}
@@ -14716,29 +15359,18 @@ Handle<Object> ExternalFloat64Array::SetValue(
Handle<ExternalFloat64Array> array,
uint32_t index,
Handle<Object> value) {
- CALL_HEAP_FUNCTION(array->GetIsolate(),
- array->SetValue(index, *value),
- Object);
-}
-
-
-MaybeObject* ExternalFloat64Array::SetValue(uint32_t index, Object* value) {
double double_value = OS::nan_value();
- Heap* heap = GetHeap();
- if (index < static_cast<uint32_t>(length())) {
- if (value->IsSmi()) {
- int int_value = Smi::cast(value)->value();
- double_value = static_cast<double>(int_value);
- } else if (value->IsHeapNumber()) {
- double_value = HeapNumber::cast(value)->value();
+ if (index < static_cast<uint32_t>(array->length())) {
+ if (value->IsNumber()) {
+ double_value = value->Number();
} else {
// Clamp undefined to NaN (default). All other types have been
// converted to a number type further up in the call chain.
ASSERT(value->IsUndefined());
}
- set(index, double_value);
+ array->set(index, double_value);
}
- return heap->AllocateHeapNumber(double_value);
+ return array->GetIsolate()->factory()->NewNumber(double_value);
}
@@ -14753,14 +15385,14 @@ Handle<PropertyCell> JSGlobalObject::EnsurePropertyCell(
Handle<JSGlobalObject> global,
Handle<Name> name) {
ASSERT(!global->HasFastProperties());
- int entry = global->property_dictionary()->FindEntry(*name);
+ int entry = global->property_dictionary()->FindEntry(name);
if (entry == NameDictionary::kNotFound) {
Isolate* isolate = global->GetIsolate();
Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(
isolate->factory()->the_hole_value());
PropertyDetails details(NONE, NORMAL, 0);
details = details.AsDeleted();
- Handle<NameDictionary> dictionary = NameDictionaryAdd(
+ Handle<NameDictionary> dictionary = NameDictionary::Add(
handle(global->property_dictionary()), name, cell, details);
global->set_properties(*dictionary);
return cell;
@@ -14772,12 +15404,6 @@ Handle<PropertyCell> JSGlobalObject::EnsurePropertyCell(
}
-MaybeObject* StringTable::LookupString(String* string, Object** s) {
- InternalizedStringKey key(string);
- return LookupKey(&key, s);
-}
-
-
// This class is used for looking up two character strings in the string table.
// If we don't have a hit we don't want to waste much time so we unroll the
// string hash calculation loop here for speed. Doesn't work if the two
@@ -14814,7 +15440,7 @@ class TwoCharHashTableKey : public HashTableKey {
#endif
}
- bool IsMatch(Object* o) {
+ bool IsMatch(Object* o) V8_OVERRIDE {
if (!o->IsString()) return false;
String* other = String::cast(o);
if (other->length() != 2) return false;
@@ -14822,17 +15448,17 @@ class TwoCharHashTableKey : public HashTableKey {
return other->Get(1) == c2_;
}
- uint32_t Hash() { return hash_; }
- uint32_t HashForObject(Object* key) {
+ uint32_t Hash() V8_OVERRIDE { return hash_; }
+ uint32_t HashForObject(Object* key) V8_OVERRIDE {
if (!key->IsString()) return 0;
return String::cast(key)->Hash();
}
- Object* AsObject(Heap* heap) {
+ Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE {
// The TwoCharHashTableKey is only used for looking in the string
// table, not for adding to it.
UNREACHABLE();
- return NULL;
+ return MaybeHandle<Object>().ToHandleChecked();
}
private:
@@ -14842,179 +15468,171 @@ class TwoCharHashTableKey : public HashTableKey {
};
-bool StringTable::LookupStringIfExists(String* string, String** result) {
+MaybeHandle<String> StringTable::InternalizeStringIfExists(
+ Isolate* isolate,
+ Handle<String> string) {
+ if (string->IsInternalizedString()) {
+ return string;
+ }
+ return LookupStringIfExists(isolate, string);
+}
+
+
+MaybeHandle<String> StringTable::LookupStringIfExists(
+ Isolate* isolate,
+ Handle<String> string) {
+ Handle<StringTable> string_table = isolate->factory()->string_table();
InternalizedStringKey key(string);
- int entry = FindEntry(&key);
+ int entry = string_table->FindEntry(&key);
if (entry == kNotFound) {
- return false;
+ return MaybeHandle<String>();
} else {
- *result = String::cast(KeyAt(entry));
+ Handle<String> result(String::cast(string_table->KeyAt(entry)), isolate);
ASSERT(StringShape(*result).IsInternalized());
- return true;
+ return result;
}
}
-bool StringTable::LookupTwoCharsStringIfExists(uint16_t c1,
- uint16_t c2,
- String** result) {
- TwoCharHashTableKey key(c1, c2, GetHeap()->HashSeed());
- int entry = FindEntry(&key);
+MaybeHandle<String> StringTable::LookupTwoCharsStringIfExists(
+ Isolate* isolate,
+ uint16_t c1,
+ uint16_t c2) {
+ Handle<StringTable> string_table = isolate->factory()->string_table();
+ TwoCharHashTableKey key(c1, c2, isolate->heap()->HashSeed());
+ int entry = string_table->FindEntry(&key);
if (entry == kNotFound) {
- return false;
+ return MaybeHandle<String>();
} else {
- *result = String::cast(KeyAt(entry));
+ Handle<String> result(String::cast(string_table->KeyAt(entry)), isolate);
ASSERT(StringShape(*result).IsInternalized());
- return true;
+ return result;
}
}
-MaybeObject* StringTable::LookupKey(HashTableKey* key, Object** s) {
- int entry = FindEntry(key);
+Handle<String> StringTable::LookupString(Isolate* isolate,
+ Handle<String> string) {
+ InternalizedStringKey key(string);
+ return LookupKey(isolate, &key);
+}
+
+
+Handle<String> StringTable::LookupKey(Isolate* isolate, HashTableKey* key) {
+ Handle<StringTable> table = isolate->factory()->string_table();
+ int entry = table->FindEntry(key);
// String already in table.
if (entry != kNotFound) {
- *s = KeyAt(entry);
- return this;
+ return handle(String::cast(table->KeyAt(entry)), isolate);
}
// Adding new string. Grow table if needed.
- Object* obj;
- { MaybeObject* maybe_obj = EnsureCapacity(1, key);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
+ table = StringTable::EnsureCapacity(table, 1, key);
// Create string object.
- Object* string;
- { MaybeObject* maybe_string = key->AsObject(GetHeap());
- if (!maybe_string->ToObject(&string)) return maybe_string;
- }
-
- // If the string table grew as part of EnsureCapacity, obj is not
- // the current string table and therefore we cannot use
- // StringTable::cast here.
- StringTable* table = reinterpret_cast<StringTable*>(obj);
+ Handle<Object> string = key->AsHandle(isolate);
+ // There must be no attempts to internalize strings that could throw
+ // InvalidStringLength error.
+ CHECK(!string.is_null());
// Add the new string and return it along with the string table.
entry = table->FindInsertionEntry(key->Hash());
- table->set(EntryToIndex(entry), string);
+ table->set(EntryToIndex(entry), *string);
table->ElementAdded();
- *s = string;
- return table;
+
+ isolate->factory()->set_string_table(table);
+ return Handle<String>::cast(string);
}
-Object* CompilationCacheTable::Lookup(String* src, Context* context) {
- SharedFunctionInfo* shared = context->closure()->shared();
- StringSharedKey key(src,
- shared,
- FLAG_use_strict ? STRICT : SLOPPY,
+Handle<Object> CompilationCacheTable::Lookup(Handle<String> src,
+ Handle<Context> context) {
+ Isolate* isolate = GetIsolate();
+ Handle<SharedFunctionInfo> shared(context->closure()->shared());
+ StringSharedKey key(src, shared, FLAG_use_strict ? STRICT : SLOPPY,
RelocInfo::kNoPosition);
int entry = FindEntry(&key);
- if (entry == kNotFound) return GetHeap()->undefined_value();
- return get(EntryToIndex(entry) + 1);
+ if (entry == kNotFound) return isolate->factory()->undefined_value();
+ return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
}
-Object* CompilationCacheTable::LookupEval(String* src,
- Context* context,
- StrictMode strict_mode,
- int scope_position) {
- StringSharedKey key(src,
- context->closure()->shared(),
- strict_mode,
- scope_position);
+Handle<Object> CompilationCacheTable::LookupEval(Handle<String> src,
+ Handle<Context> context,
+ StrictMode strict_mode,
+ int scope_position) {
+ Isolate* isolate = GetIsolate();
+ Handle<SharedFunctionInfo> shared(context->closure()->shared());
+ StringSharedKey key(src, shared, strict_mode, scope_position);
int entry = FindEntry(&key);
- if (entry == kNotFound) return GetHeap()->undefined_value();
- return get(EntryToIndex(entry) + 1);
+ if (entry == kNotFound) return isolate->factory()->undefined_value();
+ return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
}
-Object* CompilationCacheTable::LookupRegExp(String* src,
- JSRegExp::Flags flags) {
+Handle<Object> CompilationCacheTable::LookupRegExp(Handle<String> src,
+ JSRegExp::Flags flags) {
+ Isolate* isolate = GetIsolate();
+ DisallowHeapAllocation no_allocation;
RegExpKey key(src, flags);
int entry = FindEntry(&key);
- if (entry == kNotFound) return GetHeap()->undefined_value();
- return get(EntryToIndex(entry) + 1);
+ if (entry == kNotFound) return isolate->factory()->undefined_value();
+ return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
}
-MaybeObject* CompilationCacheTable::Put(String* src,
- Context* context,
- Object* value) {
- SharedFunctionInfo* shared = context->closure()->shared();
- StringSharedKey key(src,
- shared,
- FLAG_use_strict ? STRICT : SLOPPY,
+Handle<CompilationCacheTable> CompilationCacheTable::Put(
+ Handle<CompilationCacheTable> cache, Handle<String> src,
+ Handle<Context> context, Handle<Object> value) {
+ Isolate* isolate = cache->GetIsolate();
+ Handle<SharedFunctionInfo> shared(context->closure()->shared());
+ StringSharedKey key(src, shared, FLAG_use_strict ? STRICT : SLOPPY,
RelocInfo::kNoPosition);
- CompilationCacheTable* cache;
- MaybeObject* maybe_cache = EnsureCapacity(1, &key);
- if (!maybe_cache->To(&cache)) return maybe_cache;
-
- Object* k;
- MaybeObject* maybe_k = key.AsObject(GetHeap());
- if (!maybe_k->To(&k)) return maybe_k;
-
+ cache = EnsureCapacity(cache, 1, &key);
+ Handle<Object> k = key.AsHandle(isolate);
int entry = cache->FindInsertionEntry(key.Hash());
- cache->set(EntryToIndex(entry), k);
- cache->set(EntryToIndex(entry) + 1, value);
+ cache->set(EntryToIndex(entry), *k);
+ cache->set(EntryToIndex(entry) + 1, *value);
cache->ElementAdded();
return cache;
}
-MaybeObject* CompilationCacheTable::PutEval(String* src,
- Context* context,
- SharedFunctionInfo* value,
- int scope_position) {
- StringSharedKey key(src,
- context->closure()->shared(),
- value->strict_mode(),
- scope_position);
- Object* obj;
- { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
-
- CompilationCacheTable* cache =
- reinterpret_cast<CompilationCacheTable*>(obj);
+Handle<CompilationCacheTable> CompilationCacheTable::PutEval(
+ Handle<CompilationCacheTable> cache, Handle<String> src,
+ Handle<Context> context, Handle<SharedFunctionInfo> value,
+ int scope_position) {
+ Isolate* isolate = cache->GetIsolate();
+ Handle<SharedFunctionInfo> shared(context->closure()->shared());
+ StringSharedKey key(src, shared, value->strict_mode(), scope_position);
+ cache = EnsureCapacity(cache, 1, &key);
+ Handle<Object> k = key.AsHandle(isolate);
int entry = cache->FindInsertionEntry(key.Hash());
-
- Object* k;
- { MaybeObject* maybe_k = key.AsObject(GetHeap());
- if (!maybe_k->ToObject(&k)) return maybe_k;
- }
-
- cache->set(EntryToIndex(entry), k);
- cache->set(EntryToIndex(entry) + 1, value);
+ cache->set(EntryToIndex(entry), *k);
+ cache->set(EntryToIndex(entry) + 1, *value);
cache->ElementAdded();
return cache;
}
-MaybeObject* CompilationCacheTable::PutRegExp(String* src,
- JSRegExp::Flags flags,
- FixedArray* value) {
+Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp(
+ Handle<CompilationCacheTable> cache, Handle<String> src,
+ JSRegExp::Flags flags, Handle<FixedArray> value) {
RegExpKey key(src, flags);
- Object* obj;
- { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
-
- CompilationCacheTable* cache =
- reinterpret_cast<CompilationCacheTable*>(obj);
+ cache = EnsureCapacity(cache, 1, &key);
int entry = cache->FindInsertionEntry(key.Hash());
// We store the value in the key slot, and compare the search key
// to the stored value with a custon IsMatch function during lookups.
- cache->set(EntryToIndex(entry), value);
- cache->set(EntryToIndex(entry) + 1, value);
+ cache->set(EntryToIndex(entry), *value);
+ cache->set(EntryToIndex(entry) + 1, *value);
cache->ElementAdded();
return cache;
}
void CompilationCacheTable::Remove(Object* value) {
+ DisallowHeapAllocation no_allocation;
Object* the_hole_value = GetHeap()->the_hole_value();
for (int entry = 0, size = Capacity(); entry < size; entry++) {
int entry_index = EntryToIndex(entry);
@@ -15032,9 +15650,9 @@ void CompilationCacheTable::Remove(Object* value) {
// StringsKey used for HashTable where key is array of internalized strings.
class StringsKey : public HashTableKey {
public:
- explicit StringsKey(FixedArray* strings) : strings_(strings) { }
+ explicit StringsKey(Handle<FixedArray> strings) : strings_(strings) { }
- bool IsMatch(Object* strings) {
+ bool IsMatch(Object* strings) V8_OVERRIDE {
FixedArray* o = FixedArray::cast(strings);
int len = strings_->length();
if (o->length() != len) return false;
@@ -15044,9 +15662,9 @@ class StringsKey : public HashTableKey {
return true;
}
- uint32_t Hash() { return HashForObject(strings_); }
+ uint32_t Hash() V8_OVERRIDE { return HashForObject(*strings_); }
- uint32_t HashForObject(Object* obj) {
+ uint32_t HashForObject(Object* obj) V8_OVERRIDE {
FixedArray* strings = FixedArray::cast(obj);
int len = strings->length();
uint32_t hash = 0;
@@ -15056,96 +15674,79 @@ class StringsKey : public HashTableKey {
return hash;
}
- Object* AsObject(Heap* heap) { return strings_; }
+ Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE { return strings_; }
private:
- FixedArray* strings_;
+ Handle<FixedArray> strings_;
};
Object* MapCache::Lookup(FixedArray* array) {
- StringsKey key(array);
+ DisallowHeapAllocation no_alloc;
+ StringsKey key(handle(array));
int entry = FindEntry(&key);
if (entry == kNotFound) return GetHeap()->undefined_value();
return get(EntryToIndex(entry) + 1);
}
-MaybeObject* MapCache::Put(FixedArray* array, Map* value) {
+Handle<MapCache> MapCache::Put(
+ Handle<MapCache> map_cache, Handle<FixedArray> array, Handle<Map> value) {
StringsKey key(array);
- Object* obj;
- { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- MapCache* cache = reinterpret_cast<MapCache*>(obj);
- int entry = cache->FindInsertionEntry(key.Hash());
- cache->set(EntryToIndex(entry), array);
- cache->set(EntryToIndex(entry) + 1, value);
- cache->ElementAdded();
- return cache;
+ Handle<MapCache> new_cache = EnsureCapacity(map_cache, 1, &key);
+ int entry = new_cache->FindInsertionEntry(key.Hash());
+ new_cache->set(EntryToIndex(entry), *array);
+ new_cache->set(EntryToIndex(entry) + 1, *value);
+ new_cache->ElementAdded();
+ return new_cache;
}
-template<typename Shape, typename Key>
-MaybeObject* Dictionary<Shape, Key>::Allocate(Heap* heap,
- int at_least_space_for,
- PretenureFlag pretenure) {
- Object* obj;
- { MaybeObject* maybe_obj =
- HashTable<Shape, Key>::Allocate(
- heap,
- at_least_space_for,
- USE_DEFAULT_MINIMUM_CAPACITY,
- pretenure);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
+template<typename Derived, typename Shape, typename Key>
+Handle<Derived> Dictionary<Derived, Shape, Key>::New(
+ Isolate* isolate,
+ int at_least_space_for,
+ PretenureFlag pretenure) {
+ ASSERT(0 <= at_least_space_for);
+ Handle<Derived> dict = DerivedHashTable::New(isolate,
+ at_least_space_for,
+ USE_DEFAULT_MINIMUM_CAPACITY,
+ pretenure);
+
// Initialize the next enumeration index.
- Dictionary<Shape, Key>::cast(obj)->
- SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
- return obj;
+ dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
+ return dict;
}
-void NameDictionary::DoGenerateNewEnumerationIndices(
- Handle<NameDictionary> dictionary) {
- CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(),
- dictionary->GenerateNewEnumerationIndices());
-}
-
-template<typename Shape, typename Key>
-MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() {
- Heap* heap = Dictionary<Shape, Key>::GetHeap();
- int length = HashTable<Shape, Key>::NumberOfElements();
+template<typename Derived, typename Shape, typename Key>
+void Dictionary<Derived, Shape, Key>::GenerateNewEnumerationIndices(
+ Handle<Derived> dictionary) {
+ Factory* factory = dictionary->GetIsolate()->factory();
+ int length = dictionary->NumberOfElements();
// Allocate and initialize iteration order array.
- Object* obj;
- { MaybeObject* maybe_obj = heap->AllocateFixedArray(length);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- FixedArray* iteration_order = FixedArray::cast(obj);
+ Handle<FixedArray> iteration_order = factory->NewFixedArray(length);
for (int i = 0; i < length; i++) {
iteration_order->set(i, Smi::FromInt(i));
}
// Allocate array with enumeration order.
- { MaybeObject* maybe_obj = heap->AllocateFixedArray(length);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- FixedArray* enumeration_order = FixedArray::cast(obj);
+ Handle<FixedArray> enumeration_order = factory->NewFixedArray(length);
// Fill the enumeration order array with property details.
- int capacity = HashTable<Shape, Key>::Capacity();
+ int capacity = dictionary->Capacity();
int pos = 0;
for (int i = 0; i < capacity; i++) {
- if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) {
- int index = DetailsAt(i).dictionary_index();
+ if (dictionary->IsKey(dictionary->KeyAt(i))) {
+ int index = dictionary->DetailsAt(i).dictionary_index();
enumeration_order->set(pos++, Smi::FromInt(index));
}
}
// Sort the arrays wrt. enumeration order.
- iteration_order->SortPairs(enumeration_order, enumeration_order->length());
+ iteration_order->SortPairs(*enumeration_order, enumeration_order->length());
// Overwrite the enumeration_order with the enumeration indices.
for (int i = 0; i < length; i++) {
@@ -15155,135 +15756,125 @@ MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() {
}
// Update the dictionary with new indices.
- capacity = HashTable<Shape, Key>::Capacity();
+ capacity = dictionary->Capacity();
pos = 0;
for (int i = 0; i < capacity; i++) {
- if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) {
+ if (dictionary->IsKey(dictionary->KeyAt(i))) {
int enum_index = Smi::cast(enumeration_order->get(pos++))->value();
- PropertyDetails details = DetailsAt(i);
+ PropertyDetails details = dictionary->DetailsAt(i);
PropertyDetails new_details = PropertyDetails(
details.attributes(), details.type(), enum_index);
- DetailsAtPut(i, new_details);
+ dictionary->DetailsAtPut(i, new_details);
}
}
// Set the next enumeration index.
- SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length);
- return this;
+ dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length);
}
-template<typename Shape, typename Key>
-MaybeObject* Dictionary<Shape, Key>::EnsureCapacity(int n, Key key) {
+
+template<typename Derived, typename Shape, typename Key>
+Handle<Derived> Dictionary<Derived, Shape, Key>::EnsureCapacity(
+ Handle<Derived> dictionary, int n, Key key) {
// Check whether there are enough enumeration indices to add n elements.
if (Shape::kIsEnumerable &&
- !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) {
+ !PropertyDetails::IsValidIndex(dictionary->NextEnumerationIndex() + n)) {
// If not, we generate new indices for the properties.
- Object* result;
- { MaybeObject* maybe_result = GenerateNewEnumerationIndices();
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
+ GenerateNewEnumerationIndices(dictionary);
}
- return HashTable<Shape, Key>::EnsureCapacity(n, key);
+ return DerivedHashTable::EnsureCapacity(dictionary, n, key);
}
-template<typename Shape, typename Key>
-Object* Dictionary<Shape, Key>::DeleteProperty(int entry,
- JSReceiver::DeleteMode mode) {
- Heap* heap = Dictionary<Shape, Key>::GetHeap();
- PropertyDetails details = DetailsAt(entry);
+template<typename Derived, typename Shape, typename Key>
+Handle<Object> Dictionary<Derived, Shape, Key>::DeleteProperty(
+ Handle<Derived> dictionary,
+ int entry,
+ JSObject::DeleteMode mode) {
+ Factory* factory = dictionary->GetIsolate()->factory();
+ PropertyDetails details = dictionary->DetailsAt(entry);
// Ignore attributes if forcing a deletion.
if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) {
- return heap->false_value();
+ return factory->false_value();
}
- SetEntry(entry, heap->the_hole_value(), heap->the_hole_value());
- HashTable<Shape, Key>::ElementRemoved();
- return heap->true_value();
-}
-
-template<typename Shape, typename Key>
-MaybeObject* Dictionary<Shape, Key>::Shrink(Key key) {
- return HashTable<Shape, Key>::Shrink(key);
+ dictionary->SetEntry(
+ entry, factory->the_hole_value(), factory->the_hole_value());
+ dictionary->ElementRemoved();
+ return factory->true_value();
}
-template<typename Shape, typename Key>
-MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) {
- int entry = this->FindEntry(key);
+template<typename Derived, typename Shape, typename Key>
+Handle<Derived> Dictionary<Derived, Shape, Key>::AtPut(
+ Handle<Derived> dictionary, Key key, Handle<Object> value) {
+ int entry = dictionary->FindEntry(key);
// If the entry is present set the value;
- if (entry != Dictionary<Shape, Key>::kNotFound) {
- ValueAtPut(entry, value);
- return this;
+ if (entry != Dictionary::kNotFound) {
+ dictionary->ValueAtPut(entry, *value);
+ return dictionary;
}
// Check whether the dictionary should be extended.
- Object* obj;
- { MaybeObject* maybe_obj = EnsureCapacity(1, key);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
-
- Object* k;
- { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key);
- if (!maybe_k->ToObject(&k)) return maybe_k;
- }
+ dictionary = EnsureCapacity(dictionary, 1, key);
+#ifdef DEBUG
+ USE(Shape::AsHandle(dictionary->GetIsolate(), key));
+#endif
PropertyDetails details = PropertyDetails(NONE, NORMAL, 0);
- return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details,
- Dictionary<Shape, Key>::Hash(key));
+ AddEntry(dictionary, key, value, details, dictionary->Hash(key));
+ return dictionary;
}
-template<typename Shape, typename Key>
-MaybeObject* Dictionary<Shape, Key>::Add(Key key,
- Object* value,
- PropertyDetails details) {
+template<typename Derived, typename Shape, typename Key>
+Handle<Derived> Dictionary<Derived, Shape, Key>::Add(
+ Handle<Derived> dictionary,
+ Key key,
+ Handle<Object> value,
+ PropertyDetails details) {
// Valdate key is absent.
- SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound));
+ SLOW_ASSERT((dictionary->FindEntry(key) == Dictionary::kNotFound));
// Check whether the dictionary should be extended.
- Object* obj;
- { MaybeObject* maybe_obj = EnsureCapacity(1, key);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
+ dictionary = EnsureCapacity(dictionary, 1, key);
- return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details,
- Dictionary<Shape, Key>::Hash(key));
+ AddEntry(dictionary, key, value, details, dictionary->Hash(key));
+ return dictionary;
}
// Add a key, value pair to the dictionary.
-template<typename Shape, typename Key>
-MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key,
- Object* value,
- PropertyDetails details,
- uint32_t hash) {
+template<typename Derived, typename Shape, typename Key>
+void Dictionary<Derived, Shape, Key>::AddEntry(
+ Handle<Derived> dictionary,
+ Key key,
+ Handle<Object> value,
+ PropertyDetails details,
+ uint32_t hash) {
// Compute the key object.
- Object* k;
- { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key);
- if (!maybe_k->ToObject(&k)) return maybe_k;
- }
+ Handle<Object> k = Shape::AsHandle(dictionary->GetIsolate(), key);
- uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash);
+ uint32_t entry = dictionary->FindInsertionEntry(hash);
// Insert element at empty or deleted entry
if (!details.IsDeleted() &&
details.dictionary_index() == 0 &&
Shape::kIsEnumerable) {
// Assign an enumeration index to the property and update
// SetNextEnumerationIndex.
- int index = NextEnumerationIndex();
+ int index = dictionary->NextEnumerationIndex();
details = PropertyDetails(details.attributes(), details.type(), index);
- SetNextEnumerationIndex(index + 1);
+ dictionary->SetNextEnumerationIndex(index + 1);
}
- SetEntry(entry, k, value, details);
- ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() ||
- Dictionary<Shape, Key>::KeyAt(entry)->IsName()));
- HashTable<Shape, Key>::ElementAdded();
- return this;
+ dictionary->SetEntry(entry, k, value, details);
+ ASSERT((dictionary->KeyAt(entry)->IsNumber() ||
+ dictionary->KeyAt(entry)->IsName()));
+ dictionary->ElementAdded();
}
void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) {
+ DisallowHeapAllocation no_allocation;
// If the dictionary requires slow elements an element has already
// been added at a high index.
if (requires_slow_elements()) return;
@@ -15301,105 +15892,86 @@ void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) {
}
}
+
Handle<SeededNumberDictionary> SeededNumberDictionary::AddNumberEntry(
Handle<SeededNumberDictionary> dictionary,
uint32_t key,
Handle<Object> value,
PropertyDetails details) {
- CALL_HEAP_FUNCTION(dictionary->GetIsolate(),
- dictionary->AddNumberEntry(key, *value, details),
- SeededNumberDictionary);
+ dictionary->UpdateMaxNumberKey(key);
+ SLOW_ASSERT(dictionary->FindEntry(key) == kNotFound);
+ return Add(dictionary, key, value, details);
}
-MaybeObject* SeededNumberDictionary::AddNumberEntry(uint32_t key,
- Object* value,
- PropertyDetails details) {
- UpdateMaxNumberKey(key);
- SLOW_ASSERT(this->FindEntry(key) == kNotFound);
- return Add(key, value, details);
-}
-
-MaybeObject* UnseededNumberDictionary::AddNumberEntry(uint32_t key,
- Object* value) {
- SLOW_ASSERT(this->FindEntry(key) == kNotFound);
- return Add(key, value, PropertyDetails(NONE, NORMAL, 0));
+Handle<UnseededNumberDictionary> UnseededNumberDictionary::AddNumberEntry(
+ Handle<UnseededNumberDictionary> dictionary,
+ uint32_t key,
+ Handle<Object> value) {
+ SLOW_ASSERT(dictionary->FindEntry(key) == kNotFound);
+ return Add(dictionary, key, value, PropertyDetails(NONE, NORMAL, 0));
}
-MaybeObject* SeededNumberDictionary::AtNumberPut(uint32_t key, Object* value) {
- UpdateMaxNumberKey(key);
- return AtPut(key, value);
+Handle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut(
+ Handle<SeededNumberDictionary> dictionary,
+ uint32_t key,
+ Handle<Object> value) {
+ dictionary->UpdateMaxNumberKey(key);
+ return AtPut(dictionary, key, value);
}
-MaybeObject* UnseededNumberDictionary::AtNumberPut(uint32_t key,
- Object* value) {
- return AtPut(key, value);
+Handle<UnseededNumberDictionary> UnseededNumberDictionary::AtNumberPut(
+ Handle<UnseededNumberDictionary> dictionary,
+ uint32_t key,
+ Handle<Object> value) {
+ return AtPut(dictionary, key, value);
}
Handle<SeededNumberDictionary> SeededNumberDictionary::Set(
Handle<SeededNumberDictionary> dictionary,
- uint32_t index,
+ uint32_t key,
Handle<Object> value,
PropertyDetails details) {
- CALL_HEAP_FUNCTION(dictionary->GetIsolate(),
- dictionary->Set(index, *value, details),
- SeededNumberDictionary);
-}
-
-
-Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set(
- Handle<UnseededNumberDictionary> dictionary,
- uint32_t index,
- Handle<Object> value) {
- CALL_HEAP_FUNCTION(dictionary->GetIsolate(),
- dictionary->Set(index, *value),
- UnseededNumberDictionary);
-}
-
-
-MaybeObject* SeededNumberDictionary::Set(uint32_t key,
- Object* value,
- PropertyDetails details) {
- int entry = FindEntry(key);
- if (entry == kNotFound) return AddNumberEntry(key, value, details);
+ int entry = dictionary->FindEntry(key);
+ if (entry == kNotFound) {
+ return AddNumberEntry(dictionary, key, value, details);
+ }
// Preserve enumeration index.
details = PropertyDetails(details.attributes(),
details.type(),
- DetailsAt(entry).dictionary_index());
- MaybeObject* maybe_object_key =
- SeededNumberDictionaryShape::AsObject(GetHeap(), key);
- Object* object_key;
- if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key;
- SetEntry(entry, object_key, value, details);
- return this;
+ dictionary->DetailsAt(entry).dictionary_index());
+ Handle<Object> object_key =
+ SeededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key);
+ dictionary->SetEntry(entry, object_key, value, details);
+ return dictionary;
}
-MaybeObject* UnseededNumberDictionary::Set(uint32_t key,
- Object* value) {
- int entry = FindEntry(key);
- if (entry == kNotFound) return AddNumberEntry(key, value);
- MaybeObject* maybe_object_key =
- UnseededNumberDictionaryShape::AsObject(GetHeap(), key);
- Object* object_key;
- if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key;
- SetEntry(entry, object_key, value);
- return this;
+Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set(
+ Handle<UnseededNumberDictionary> dictionary,
+ uint32_t key,
+ Handle<Object> value) {
+ int entry = dictionary->FindEntry(key);
+ if (entry == kNotFound) return AddNumberEntry(dictionary, key, value);
+ Handle<Object> object_key =
+ UnseededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key);
+ dictionary->SetEntry(entry, object_key, value);
+ return dictionary;
}
-template<typename Shape, typename Key>
-int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes(
+template<typename Derived, typename Shape, typename Key>
+int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes(
PropertyAttributes filter) {
- int capacity = HashTable<Shape, Key>::Capacity();
+ int capacity = DerivedHashTable::Capacity();
int result = 0;
for (int i = 0; i < capacity; i++) {
- Object* k = HashTable<Shape, Key>::KeyAt(i);
- if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) {
+ Object* k = DerivedHashTable::KeyAt(i);
+ if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) {
PropertyDetails details = DetailsAt(i);
if (details.IsDeleted()) continue;
PropertyAttributes attr = details.attributes();
@@ -15410,31 +15982,31 @@ int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes(
}
-template<typename Shape, typename Key>
-int Dictionary<Shape, Key>::NumberOfEnumElements() {
+template<typename Derived, typename Shape, typename Key>
+int Dictionary<Derived, Shape, Key>::NumberOfEnumElements() {
return NumberOfElementsFilterAttributes(
static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC));
}
-template<typename Shape, typename Key>
-void Dictionary<Shape, Key>::CopyKeysTo(
+template<typename Derived, typename Shape, typename Key>
+void Dictionary<Derived, Shape, Key>::CopyKeysTo(
FixedArray* storage,
PropertyAttributes filter,
- typename Dictionary<Shape, Key>::SortMode sort_mode) {
+ typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) {
ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter));
- int capacity = HashTable<Shape, Key>::Capacity();
+ int capacity = DerivedHashTable::Capacity();
int index = 0;
for (int i = 0; i < capacity; i++) {
- Object* k = HashTable<Shape, Key>::KeyAt(i);
- if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) {
+ Object* k = DerivedHashTable::KeyAt(i);
+ if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) {
PropertyDetails details = DetailsAt(i);
if (details.IsDeleted()) continue;
PropertyAttributes attr = details.attributes();
if ((attr & filter) == 0) storage->set(index++, k);
}
}
- if (sort_mode == Dictionary<Shape, Key>::SORTED) {
+ if (sort_mode == Dictionary::SORTED) {
storage->SortPairs(storage, index);
}
ASSERT(storage->length() >= index);
@@ -15476,24 +16048,24 @@ void NameDictionary::CopyEnumKeysTo(FixedArray* storage) {
}
-template<typename Shape, typename Key>
-void Dictionary<Shape, Key>::CopyKeysTo(
+template<typename Derived, typename Shape, typename Key>
+void Dictionary<Derived, Shape, Key>::CopyKeysTo(
FixedArray* storage,
int index,
PropertyAttributes filter,
- typename Dictionary<Shape, Key>::SortMode sort_mode) {
+ typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) {
ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter));
- int capacity = HashTable<Shape, Key>::Capacity();
+ int capacity = DerivedHashTable::Capacity();
for (int i = 0; i < capacity; i++) {
- Object* k = HashTable<Shape, Key>::KeyAt(i);
- if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) {
+ Object* k = DerivedHashTable::KeyAt(i);
+ if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) {
PropertyDetails details = DetailsAt(i);
if (details.IsDeleted()) continue;
PropertyAttributes attr = details.attributes();
if ((attr & filter) == 0) storage->set(index++, k);
}
}
- if (sort_mode == Dictionary<Shape, Key>::SORTED) {
+ if (sort_mode == Dictionary::SORTED) {
storage->SortPairs(storage, index);
}
ASSERT(storage->length() >= index);
@@ -15501,12 +16073,12 @@ void Dictionary<Shape, Key>::CopyKeysTo(
// Backwards lookup (slow).
-template<typename Shape, typename Key>
-Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) {
- int capacity = HashTable<Shape, Key>::Capacity();
+template<typename Derived, typename Shape, typename Key>
+Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) {
+ int capacity = DerivedHashTable::Capacity();
for (int i = 0; i < capacity; i++) {
- Object* k = HashTable<Shape, Key>::KeyAt(i);
- if (Dictionary<Shape, Key>::IsKey(k)) {
+ Object* k = DerivedHashTable::KeyAt(i);
+ if (Dictionary::IsKey(k)) {
Object* e = ValueAt(i);
if (e->IsPropertyCell()) {
e = PropertyCell::cast(e)->value();
@@ -15514,344 +16086,608 @@ Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) {
if (e == value) return k;
}
}
- Heap* heap = Dictionary<Shape, Key>::GetHeap();
+ Heap* heap = Dictionary::GetHeap();
return heap->undefined_value();
}
-MaybeObject* NameDictionary::TransformPropertiesToFastFor(
- JSObject* obj, int unused_property_fields) {
- // Make sure we preserve dictionary representation if there are too many
- // descriptors.
- int number_of_elements = NumberOfElements();
- if (number_of_elements > kMaxNumberOfDescriptors) return obj;
+Object* ObjectHashTable::Lookup(Handle<Object> key) {
+ DisallowHeapAllocation no_gc;
+ ASSERT(IsKey(*key));
- if (number_of_elements != NextEnumerationIndex()) {
- MaybeObject* maybe_result = GenerateNewEnumerationIndices();
- if (maybe_result->IsFailure()) return maybe_result;
+ // If the object does not have an identity hash, it was never used as a key.
+ Object* hash = key->GetHash();
+ if (hash->IsUndefined()) {
+ return GetHeap()->the_hole_value();
}
+ int entry = FindEntry(key);
+ if (entry == kNotFound) return GetHeap()->the_hole_value();
+ return get(EntryToIndex(entry) + 1);
+}
- int instance_descriptor_length = 0;
- int number_of_fields = 0;
- Heap* heap = GetHeap();
+Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
+ Handle<Object> key,
+ Handle<Object> value) {
+ ASSERT(table->IsKey(*key));
- // Compute the length of the instance descriptor.
- int capacity = Capacity();
- for (int i = 0; i < capacity; i++) {
- Object* k = KeyAt(i);
- if (IsKey(k)) {
- Object* value = ValueAt(i);
- PropertyType type = DetailsAt(i).type();
- ASSERT(type != FIELD);
- instance_descriptor_length++;
- if (type == NORMAL && !value->IsJSFunction()) {
- number_of_fields += 1;
- }
- }
- }
+ Isolate* isolate = table->GetIsolate();
- int inobject_props = obj->map()->inobject_properties();
+ // Make sure the key object has an identity hash code.
+ Handle<Object> hash = Object::GetOrCreateHash(key, isolate);
- // Allocate new map.
- Map* new_map;
- MaybeObject* maybe_new_map = obj->map()->CopyDropDescriptors();
- if (!maybe_new_map->To(&new_map)) return maybe_new_map;
- new_map->set_dictionary_map(false);
+ int entry = table->FindEntry(key);
- if (instance_descriptor_length == 0) {
- ASSERT_LE(unused_property_fields, inobject_props);
- // Transform the object.
- new_map->set_unused_property_fields(inobject_props);
- obj->set_map(new_map);
- obj->set_properties(heap->empty_fixed_array());
- // Check that it really works.
- ASSERT(obj->HasFastProperties());
- return obj;
+ // Check whether to perform removal operation.
+ if (value->IsTheHole()) {
+ if (entry == kNotFound) return table;
+ table->RemoveEntry(entry);
+ return Shrink(table, key);
}
- // Allocate the instance descriptor.
- DescriptorArray* descriptors;
- MaybeObject* maybe_descriptors =
- DescriptorArray::Allocate(GetIsolate(), instance_descriptor_length);
- if (!maybe_descriptors->To(&descriptors)) {
- return maybe_descriptors;
+ // Key is already in table, just overwrite value.
+ if (entry != kNotFound) {
+ table->set(EntryToIndex(entry) + 1, *value);
+ return table;
}
- DescriptorArray::WhitenessWitness witness(descriptors);
+ // Check whether the hash table should be extended.
+ table = EnsureCapacity(table, 1, key);
+ table->AddEntry(table->FindInsertionEntry(Handle<Smi>::cast(hash)->value()),
+ *key,
+ *value);
+ return table;
+}
- int number_of_allocated_fields =
- number_of_fields + unused_property_fields - inobject_props;
- if (number_of_allocated_fields < 0) {
- // There is enough inobject space for all fields (including unused).
- number_of_allocated_fields = 0;
- unused_property_fields = inobject_props - number_of_fields;
- }
- // Allocate the fixed array for the fields.
- FixedArray* fields;
- MaybeObject* maybe_fields =
- heap->AllocateFixedArray(number_of_allocated_fields);
- if (!maybe_fields->To(&fields)) return maybe_fields;
+void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) {
+ set(EntryToIndex(entry), key);
+ set(EntryToIndex(entry) + 1, value);
+ ElementAdded();
+}
- // Fill in the instance descriptor and the fields.
- int current_offset = 0;
- for (int i = 0; i < capacity; i++) {
- Object* k = KeyAt(i);
- if (IsKey(k)) {
- Object* value = ValueAt(i);
- Name* key;
- if (k->IsSymbol()) {
- key = Symbol::cast(k);
- } else {
- // Ensure the key is a unique name before writing into the
- // instance descriptor.
- MaybeObject* maybe_key = heap->InternalizeString(String::cast(k));
- if (!maybe_key->To(&key)) return maybe_key;
- }
- PropertyDetails details = DetailsAt(i);
- int enumeration_index = details.dictionary_index();
- PropertyType type = details.type();
-
- if (value->IsJSFunction()) {
- ConstantDescriptor d(key, value, details.attributes());
- descriptors->Set(enumeration_index - 1, &d, witness);
- } else if (type == NORMAL) {
- if (current_offset < inobject_props) {
- obj->InObjectPropertyAtPut(current_offset,
- value,
- UPDATE_WRITE_BARRIER);
- } else {
- int offset = current_offset - inobject_props;
- fields->set(offset, value);
- }
- FieldDescriptor d(key,
- current_offset++,
- details.attributes(),
- // TODO(verwaest): value->OptimalRepresentation();
- Representation::Tagged());
- descriptors->Set(enumeration_index - 1, &d, witness);
- } else if (type == CALLBACKS) {
- CallbacksDescriptor d(key,
- value,
- details.attributes());
- descriptors->Set(enumeration_index - 1, &d, witness);
- } else {
- UNREACHABLE();
- }
- }
- }
- ASSERT(current_offset == number_of_fields);
+void ObjectHashTable::RemoveEntry(int entry) {
+ set_the_hole(EntryToIndex(entry));
+ set_the_hole(EntryToIndex(entry) + 1);
+ ElementRemoved();
+}
- descriptors->Sort();
- new_map->InitializeDescriptors(descriptors);
- new_map->set_unused_property_fields(unused_property_fields);
+Object* WeakHashTable::Lookup(Handle<Object> key) {
+ DisallowHeapAllocation no_gc;
+ ASSERT(IsKey(*key));
+ int entry = FindEntry(key);
+ if (entry == kNotFound) return GetHeap()->the_hole_value();
+ return get(EntryToValueIndex(entry));
+}
- // Transform the object.
- obj->set_map(new_map);
- obj->set_properties(fields);
- ASSERT(obj->IsJSObject());
+Handle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table,
+ Handle<Object> key,
+ Handle<Object> value) {
+ ASSERT(table->IsKey(*key));
+ int entry = table->FindEntry(key);
+ // Key is already in table, just overwrite value.
+ if (entry != kNotFound) {
+ table->set(EntryToValueIndex(entry), *value);
+ return table;
+ }
- // Check that it really works.
- ASSERT(obj->HasFastProperties());
+ // Check whether the hash table should be extended.
+ table = EnsureCapacity(table, 1, key, TENURED);
- return obj;
+ table->AddEntry(table->FindInsertionEntry(table->Hash(key)), key, value);
+ return table;
}
-Handle<ObjectHashSet> ObjectHashSet::EnsureCapacity(
- Handle<ObjectHashSet> table,
- int n,
- Handle<Object> key,
- PretenureFlag pretenure) {
- Handle<HashTable<ObjectHashTableShape<1>, Object*> > table_base = table;
- CALL_HEAP_FUNCTION(table_base->GetIsolate(),
- table_base->EnsureCapacity(n, *key, pretenure),
- ObjectHashSet);
+void WeakHashTable::AddEntry(int entry,
+ Handle<Object> key,
+ Handle<Object> value) {
+ DisallowHeapAllocation no_allocation;
+ set(EntryToIndex(entry), *key);
+ set(EntryToValueIndex(entry), *value);
+ ElementAdded();
}
-Handle<ObjectHashSet> ObjectHashSet::Shrink(Handle<ObjectHashSet> table,
- Handle<Object> key) {
- Handle<HashTable<ObjectHashTableShape<1>, Object*> > table_base = table;
- CALL_HEAP_FUNCTION(table_base->GetIsolate(),
- table_base->Shrink(*key),
- ObjectHashSet);
+template<class Derived, class Iterator, int entrysize>
+Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Allocate(
+ Isolate* isolate, int capacity, PretenureFlag pretenure) {
+ // Capacity must be a power of two, since we depend on being able
+ // to divide and multiple by 2 (kLoadFactor) to derive capacity
+ // from number of buckets. If we decide to change kLoadFactor
+ // to something other than 2, capacity should be stored as another
+ // field of this object.
+ capacity = RoundUpToPowerOf2(Max(kMinCapacity, capacity));
+ if (capacity > kMaxCapacity) {
+ v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true);
+ }
+ int num_buckets = capacity / kLoadFactor;
+ Handle<FixedArray> backing_store = isolate->factory()->NewFixedArray(
+ kHashTableStartIndex + num_buckets + (capacity * kEntrySize), pretenure);
+ backing_store->set_map_no_write_barrier(
+ isolate->heap()->ordered_hash_table_map());
+ Handle<Derived> table = Handle<Derived>::cast(backing_store);
+ for (int i = 0; i < num_buckets; ++i) {
+ table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound));
+ }
+ table->SetNumberOfBuckets(num_buckets);
+ table->SetNumberOfElements(0);
+ table->SetNumberOfDeletedElements(0);
+ table->set_iterators(isolate->heap()->undefined_value());
+ return table;
}
-bool ObjectHashSet::Contains(Object* key) {
- ASSERT(IsKey(key));
+template<class Derived, class Iterator, int entrysize>
+Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::EnsureGrowable(
+ Handle<Derived> table) {
+ int nof = table->NumberOfElements();
+ int nod = table->NumberOfDeletedElements();
+ int capacity = table->Capacity();
+ if ((nof + nod) < capacity) return table;
+ // Don't need to grow if we can simply clear out deleted entries instead.
+ // Note that we can't compact in place, though, so we always allocate
+ // a new table.
+ return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity);
+}
- // If the object does not have an identity hash, it was never used as a key.
- Object* hash = key->GetHash();
- if (hash->IsUndefined()) return false;
- return (FindEntry(key) != kNotFound);
+template<class Derived, class Iterator, int entrysize>
+Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Shrink(
+ Handle<Derived> table) {
+ int nof = table->NumberOfElements();
+ int capacity = table->Capacity();
+ if (nof > (capacity >> 2)) return table;
+ return Rehash(table, capacity / 2);
}
-Handle<ObjectHashSet> ObjectHashSet::Add(Handle<ObjectHashSet> table,
- Handle<Object> key) {
- ASSERT(table->IsKey(*key));
-
- // Make sure the key object has an identity hash code.
- Handle<Object> object_hash = Object::GetOrCreateHash(key,
- table->GetIsolate());
+template<class Derived, class Iterator, int entrysize>
+Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Clear(
+ Handle<Derived> table) {
+ Handle<Derived> new_table =
+ Allocate(table->GetIsolate(),
+ kMinCapacity,
+ table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
- int entry = table->FindEntry(*key);
+ new_table->set_iterators(table->iterators());
+ table->set_iterators(table->GetHeap()->undefined_value());
- // Check whether key is already present.
- if (entry != kNotFound) return table;
+ DisallowHeapAllocation no_allocation;
+ for (Object* object = new_table->iterators();
+ !object->IsUndefined();
+ object = Iterator::cast(object)->next_iterator()) {
+ Iterator::cast(object)->TableCleared();
+ Iterator::cast(object)->set_table(*new_table);
+ }
- // Check whether the hash set should be extended and add entry.
- Handle<ObjectHashSet> new_table =
- ObjectHashSet::EnsureCapacity(table, 1, key);
- entry = new_table->FindInsertionEntry(Smi::cast(*object_hash)->value());
- new_table->set(EntryToIndex(entry), *key);
- new_table->ElementAdded();
return new_table;
}
-Handle<ObjectHashSet> ObjectHashSet::Remove(Handle<ObjectHashSet> table,
- Handle<Object> key) {
- ASSERT(table->IsKey(*key));
+template<class Derived, class Iterator, int entrysize>
+Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash(
+ Handle<Derived> table, int new_capacity) {
+ Handle<Derived> new_table =
+ Allocate(table->GetIsolate(),
+ new_capacity,
+ table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
+ int nof = table->NumberOfElements();
+ int nod = table->NumberOfDeletedElements();
+ int new_buckets = new_table->NumberOfBuckets();
+ int new_entry = 0;
+ for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) {
+ Object* key = table->KeyAt(old_entry);
+ if (key->IsTheHole()) continue;
+ Object* hash = key->GetHash();
+ int bucket = Smi::cast(hash)->value() & (new_buckets - 1);
+ Object* chain_entry = new_table->get(kHashTableStartIndex + bucket);
+ new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry));
+ int new_index = new_table->EntryToIndex(new_entry);
+ int old_index = table->EntryToIndex(old_entry);
+ for (int i = 0; i < entrysize; ++i) {
+ Object* value = table->get(old_index + i);
+ new_table->set(new_index + i, value);
+ }
+ new_table->set(new_index + kChainOffset, chain_entry);
+ ++new_entry;
+ }
+ new_table->SetNumberOfElements(nof);
+
+ new_table->set_iterators(table->iterators());
+ table->set_iterators(table->GetHeap()->undefined_value());
- // If the object does not have an identity hash, it was never used as a key.
- if (key->GetHash()->IsUndefined()) return table;
+ DisallowHeapAllocation no_allocation;
+ for (Object* object = new_table->iterators();
+ !object->IsUndefined();
+ object = Iterator::cast(object)->next_iterator()) {
+ Iterator::cast(object)->TableCompacted();
+ Iterator::cast(object)->set_table(*new_table);
+ }
- int entry = table->FindEntry(*key);
+ return new_table;
+}
- // Check whether key is actually present.
- if (entry == kNotFound) return table;
- // Remove entry and try to shrink this hash set.
- table->set_the_hole(EntryToIndex(entry));
- table->ElementRemoved();
+template<class Derived, class Iterator, int entrysize>
+int OrderedHashTable<Derived, Iterator, entrysize>::FindEntry(
+ Handle<Object> key) {
+ DisallowHeapAllocation no_gc;
+ ASSERT(!key->IsTheHole());
+ Object* hash = key->GetHash();
+ if (hash->IsUndefined()) return kNotFound;
+ for (int entry = HashToEntry(Smi::cast(hash)->value());
+ entry != kNotFound;
+ entry = ChainAt(entry)) {
+ Object* candidate = KeyAt(entry);
+ if (candidate->SameValue(*key))
+ return entry;
+ }
+ return kNotFound;
+}
- return ObjectHashSet::Shrink(table, key);
+
+template<class Derived, class Iterator, int entrysize>
+int OrderedHashTable<Derived, Iterator, entrysize>::AddEntry(int hash) {
+ int entry = UsedCapacity();
+ int bucket = HashToBucket(hash);
+ int index = EntryToIndex(entry);
+ Object* chain_entry = get(kHashTableStartIndex + bucket);
+ set(kHashTableStartIndex + bucket, Smi::FromInt(entry));
+ set(index + kChainOffset, chain_entry);
+ SetNumberOfElements(NumberOfElements() + 1);
+ return index;
}
-Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity(
- Handle<ObjectHashTable> table,
- int n,
- Handle<Object> key,
- PretenureFlag pretenure) {
- Handle<HashTable<ObjectHashTableShape<2>, Object*> > table_base = table;
- CALL_HEAP_FUNCTION(table_base->GetIsolate(),
- table_base->EnsureCapacity(n, *key, pretenure),
- ObjectHashTable);
+template<class Derived, class Iterator, int entrysize>
+void OrderedHashTable<Derived, Iterator, entrysize>::RemoveEntry(int entry) {
+ int index = EntryToIndex(entry);
+ for (int i = 0; i < entrysize; ++i) {
+ set_the_hole(index + i);
+ }
+ SetNumberOfElements(NumberOfElements() - 1);
+ SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
+
+ DisallowHeapAllocation no_allocation;
+ for (Object* object = iterators();
+ !object->IsUndefined();
+ object = Iterator::cast(object)->next_iterator()) {
+ Iterator::cast(object)->EntryRemoved(entry);
+ }
}
-Handle<ObjectHashTable> ObjectHashTable::Shrink(
- Handle<ObjectHashTable> table, Handle<Object> key) {
- Handle<HashTable<ObjectHashTableShape<2>, Object*> > table_base = table;
- CALL_HEAP_FUNCTION(table_base->GetIsolate(),
- table_base->Shrink(*key),
- ObjectHashTable);
+template Handle<OrderedHashSet>
+OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::Allocate(
+ Isolate* isolate, int capacity, PretenureFlag pretenure);
+
+template Handle<OrderedHashSet>
+OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::EnsureGrowable(
+ Handle<OrderedHashSet> table);
+
+template Handle<OrderedHashSet>
+OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::Shrink(
+ Handle<OrderedHashSet> table);
+
+template Handle<OrderedHashSet>
+OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::Clear(
+ Handle<OrderedHashSet> table);
+
+template int
+OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::FindEntry(
+ Handle<Object> key);
+
+template int
+OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::AddEntry(int hash);
+
+template void
+OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::RemoveEntry(int entry);
+
+
+template Handle<OrderedHashMap>
+OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Allocate(
+ Isolate* isolate, int capacity, PretenureFlag pretenure);
+
+template Handle<OrderedHashMap>
+OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::EnsureGrowable(
+ Handle<OrderedHashMap> table);
+
+template Handle<OrderedHashMap>
+OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Shrink(
+ Handle<OrderedHashMap> table);
+
+template Handle<OrderedHashMap>
+OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Clear(
+ Handle<OrderedHashMap> table);
+
+template int
+OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::FindEntry(
+ Handle<Object> key);
+
+template int
+OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::AddEntry(int hash);
+
+template void
+OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::RemoveEntry(int entry);
+
+
+bool OrderedHashSet::Contains(Handle<Object> key) {
+ return FindEntry(key) != kNotFound;
}
-Object* ObjectHashTable::Lookup(Object* key) {
- ASSERT(IsKey(key));
+Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table,
+ Handle<Object> key) {
+ if (table->FindEntry(key) != kNotFound) return table;
- // If the object does not have an identity hash, it was never used as a key.
- Object* hash = key->GetHash();
- if (hash->IsUndefined()) {
- return GetHeap()->the_hole_value();
- }
- int entry = FindEntry(key);
- if (entry == kNotFound) return GetHeap()->the_hole_value();
- return get(EntryToIndex(entry) + 1);
+ table = EnsureGrowable(table);
+
+ Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate());
+ int index = table->AddEntry(Smi::cast(*hash)->value());
+ table->set(index, *key);
+ return table;
}
-Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
- Handle<Object> key,
- Handle<Object> value) {
- ASSERT(table->IsKey(*key));
+Handle<OrderedHashSet> OrderedHashSet::Remove(Handle<OrderedHashSet> table,
+ Handle<Object> key) {
+ int entry = table->FindEntry(key);
+ if (entry == kNotFound) return table;
+ table->RemoveEntry(entry);
+ return Shrink(table);
+}
- Isolate* isolate = table->GetIsolate();
- // Make sure the key object has an identity hash code.
- Handle<Object> hash = Object::GetOrCreateHash(key, isolate);
+Object* OrderedHashMap::Lookup(Handle<Object> key) {
+ DisallowHeapAllocation no_gc;
+ int entry = FindEntry(key);
+ if (entry == kNotFound) return GetHeap()->the_hole_value();
+ return ValueAt(entry);
+}
- int entry = table->FindEntry(*key);
- // Check whether to perform removal operation.
+Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table,
+ Handle<Object> key,
+ Handle<Object> value) {
+ int entry = table->FindEntry(key);
+
if (value->IsTheHole()) {
if (entry == kNotFound) return table;
table->RemoveEntry(entry);
- return Shrink(table, key);
+ return Shrink(table);
}
- // Key is already in table, just overwrite value.
if (entry != kNotFound) {
- table->set(EntryToIndex(entry) + 1, *value);
+ table->set(table->EntryToIndex(entry) + kValueOffset, *value);
return table;
}
- // Check whether the hash table should be extended.
- table = EnsureCapacity(table, 1, key);
- table->AddEntry(table->FindInsertionEntry(Handle<Smi>::cast(hash)->value()),
- *key,
- *value);
+ table = EnsureGrowable(table);
+
+ Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate());
+ int index = table->AddEntry(Smi::cast(*hash)->value());
+ table->set(index, *key);
+ table->set(index + kValueOffset, *value);
return table;
}
-void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) {
- set(EntryToIndex(entry), key);
- set(EntryToIndex(entry) + 1, value);
- ElementAdded();
+template<class Derived, class TableType>
+void OrderedHashTableIterator<Derived, TableType>::EntryRemoved(int index) {
+ int i = this->index()->value();
+ if (index < i) {
+ set_count(Smi::FromInt(count()->value() - 1));
+ }
+ if (index == i) {
+ Seek();
+ }
}
-void ObjectHashTable::RemoveEntry(int entry) {
- set_the_hole(EntryToIndex(entry));
- set_the_hole(EntryToIndex(entry) + 1);
- ElementRemoved();
+template<class Derived, class TableType>
+void OrderedHashTableIterator<Derived, TableType>::Close() {
+ if (Closed()) return;
+
+ DisallowHeapAllocation no_allocation;
+
+ Object* undefined = GetHeap()->undefined_value();
+ TableType* table = TableType::cast(this->table());
+ Object* previous = previous_iterator();
+ Object* next = next_iterator();
+
+ if (previous == undefined) {
+ ASSERT_EQ(table->iterators(), this);
+ table->set_iterators(next);
+ } else {
+ ASSERT_EQ(Derived::cast(previous)->next_iterator(), this);
+ Derived::cast(previous)->set_next_iterator(next);
+ }
+
+ if (!next->IsUndefined()) {
+ ASSERT_EQ(Derived::cast(next)->previous_iterator(), this);
+ Derived::cast(next)->set_previous_iterator(previous);
+ }
+
+ set_previous_iterator(undefined);
+ set_next_iterator(undefined);
+ set_table(undefined);
}
-Object* WeakHashTable::Lookup(Object* key) {
- ASSERT(IsKey(key));
- int entry = FindEntry(key);
- if (entry == kNotFound) return GetHeap()->the_hole_value();
- return get(EntryToValueIndex(entry));
+template<class Derived, class TableType>
+void OrderedHashTableIterator<Derived, TableType>::Seek() {
+ ASSERT(!Closed());
+
+ DisallowHeapAllocation no_allocation;
+
+ int index = this->index()->value();
+
+ TableType* table = TableType::cast(this->table());
+ int used_capacity = table->UsedCapacity();
+
+ while (index < used_capacity && table->KeyAt(index)->IsTheHole()) {
+ index++;
+ }
+ set_index(Smi::FromInt(index));
}
-MaybeObject* WeakHashTable::Put(Object* key, Object* value) {
- ASSERT(IsKey(key));
- int entry = FindEntry(key);
- // Key is already in table, just overwrite value.
- if (entry != kNotFound) {
- set(EntryToValueIndex(entry), value);
- return this;
+template<class Derived, class TableType>
+void OrderedHashTableIterator<Derived, TableType>::MoveNext() {
+ ASSERT(!Closed());
+
+ set_index(Smi::FromInt(index()->value() + 1));
+ set_count(Smi::FromInt(count()->value() + 1));
+ Seek();
+}
+
+
+template<class Derived, class TableType>
+Handle<JSObject> OrderedHashTableIterator<Derived, TableType>::Next(
+ Handle<Derived> iterator) {
+ Isolate* isolate = iterator->GetIsolate();
+ Factory* factory = isolate->factory();
+
+ Handle<Object> object(iterator->table(), isolate);
+
+ if (!object->IsUndefined()) {
+ Handle<TableType> table = Handle<TableType>::cast(object);
+ int index = iterator->index()->value();
+ if (index < table->UsedCapacity()) {
+ int entry_index = table->EntryToIndex(index);
+ iterator->MoveNext();
+ Handle<Object> value = Derived::ValueForKind(iterator, entry_index);
+ return factory->NewIteratorResultObject(value, false);
+ } else {
+ iterator->Close();
+ }
}
- // Check whether the hash table should be extended.
- Object* obj;
- { MaybeObject* maybe_obj = EnsureCapacity(1, key, TENURED);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+ return factory->NewIteratorResultObject(factory->undefined_value(), true);
+}
+
+
+template<class Derived, class TableType>
+Handle<Derived> OrderedHashTableIterator<Derived, TableType>::CreateInternal(
+ Handle<Map> map,
+ Handle<TableType> table,
+ int kind) {
+ Isolate* isolate = table->GetIsolate();
+
+ Handle<Object> undefined = isolate->factory()->undefined_value();
+
+ Handle<Derived> new_iterator = Handle<Derived>::cast(
+ isolate->factory()->NewJSObjectFromMap(map));
+ new_iterator->set_previous_iterator(*undefined);
+ new_iterator->set_table(*table);
+ new_iterator->set_index(Smi::FromInt(0));
+ new_iterator->set_count(Smi::FromInt(0));
+ new_iterator->set_kind(Smi::FromInt(kind));
+
+ Handle<Object> old_iterator(table->iterators(), isolate);
+ if (!old_iterator->IsUndefined()) {
+ Handle<Derived>::cast(old_iterator)->set_previous_iterator(*new_iterator);
+ new_iterator->set_next_iterator(*old_iterator);
+ } else {
+ new_iterator->set_next_iterator(*undefined);
}
- WeakHashTable* table = WeakHashTable::cast(obj);
- table->AddEntry(table->FindInsertionEntry(Hash(key)), key, value);
- return table;
+
+ table->set_iterators(*new_iterator);
+
+ return new_iterator;
}
-void WeakHashTable::AddEntry(int entry, Object* key, Object* value) {
- set(EntryToIndex(entry), key);
- set(EntryToValueIndex(entry), value);
- ElementAdded();
+template void
+OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::EntryRemoved(
+ int index);
+
+template void
+OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::Close();
+
+template Handle<JSObject>
+OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::Next(
+ Handle<JSSetIterator> iterator);
+
+template Handle<JSSetIterator>
+OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::CreateInternal(
+ Handle<Map> map, Handle<OrderedHashSet> table, int kind);
+
+
+template void
+OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::EntryRemoved(
+ int index);
+
+template void
+OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::Close();
+
+template Handle<JSObject>
+OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::Next(
+ Handle<JSMapIterator> iterator);
+
+template Handle<JSMapIterator>
+OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::CreateInternal(
+ Handle<Map> map, Handle<OrderedHashMap> table, int kind);
+
+
+Handle<Object> JSSetIterator::ValueForKind(
+ Handle<JSSetIterator> iterator, int entry_index) {
+ int kind = iterator->kind()->value();
+ // Set.prototype only has values and entries.
+ ASSERT(kind == kKindValues || kind == kKindEntries);
+
+ Isolate* isolate = iterator->GetIsolate();
+ Factory* factory = isolate->factory();
+
+ Handle<OrderedHashSet> table(
+ OrderedHashSet::cast(iterator->table()), isolate);
+ Handle<Object> value = Handle<Object>(table->get(entry_index), isolate);
+
+ if (kind == kKindEntries) {
+ Handle<FixedArray> array = factory->NewFixedArray(2);
+ array->set(0, *value);
+ array->set(1, *value);
+ return factory->NewJSArrayWithElements(array);
+ }
+
+ return value;
+}
+
+
+Handle<Object> JSMapIterator::ValueForKind(
+ Handle<JSMapIterator> iterator, int entry_index) {
+ int kind = iterator->kind()->value();
+ ASSERT(kind == kKindKeys || kind == kKindValues || kind == kKindEntries);
+
+ Isolate* isolate = iterator->GetIsolate();
+ Factory* factory = isolate->factory();
+
+ Handle<OrderedHashMap> table(
+ OrderedHashMap::cast(iterator->table()), isolate);
+
+ switch (kind) {
+ case kKindKeys:
+ return Handle<Object>(table->get(entry_index), isolate);
+
+ case kKindValues:
+ return Handle<Object>(table->get(entry_index + 1), isolate);
+
+ case kKindEntries: {
+ Handle<Object> key(table->get(entry_index), isolate);
+ Handle<Object> value(table->get(entry_index + 1), isolate);
+ Handle<FixedArray> array = factory->NewFixedArray(2);
+ array->set(0, *key);
+ array->set(1, *value);
+ return factory->NewJSArrayWithElements(array);
+ }
+ }
+
+ UNREACHABLE();
+ return factory->undefined_value();
}
@@ -15907,7 +16743,6 @@ Handle<DeclaredAccessorDescriptor> DeclaredAccessorDescriptor::Create(
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
// Check if there is a break point at this code position.
bool DebugInfo::HasBreakPoint(int code_position) {
// Get the break point info object for this code position.
@@ -16161,7 +16996,6 @@ int BreakPointInfo::GetBreakPointCount() {
// Multiple break points.
return FixedArray::cast(break_point_objects())->length();
}
-#endif // ENABLE_DEBUGGER_SUPPORT
Object* JSDate::GetField(Object* object, Smi* index) {
@@ -16342,6 +17176,10 @@ Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer(
ASSERT(IsFixedTypedArrayElementsKind(map->elements_kind()));
+ Handle<Map> new_map = Map::TransitionElementsTo(
+ map,
+ FixedToExternalElementsKind(map->elements_kind()));
+
Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
Handle<FixedTypedArrayBase> fixed_typed_array(
FixedTypedArrayBase::cast(typed_array->elements()));
@@ -16354,14 +17192,11 @@ Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer(
isolate->factory()->NewExternalArray(
fixed_typed_array->length(), typed_array->type(),
static_cast<uint8_t*>(buffer->backing_store()));
- Handle<Map> new_map = JSObject::GetElementsTransitionMap(
- typed_array,
- FixedToExternalElementsKind(map->elements_kind()));
buffer->set_weak_first_view(*typed_array);
ASSERT(typed_array->weak_next() == isolate->heap()->undefined_value());
typed_array->set_buffer(*buffer);
- typed_array->set_map_and_elements(*new_map, *new_elements);
+ JSObject::SetMapAndElements(typed_array, new_map, new_elements);
return buffer;
}
@@ -16423,14 +17258,16 @@ void PropertyCell::SetValueInferType(Handle<PropertyCell> cell,
}
-void PropertyCell::AddDependentCompilationInfo(CompilationInfo* info) {
- Handle<DependentCode> dep(dependent_code());
+// static
+void PropertyCell::AddDependentCompilationInfo(Handle<PropertyCell> cell,
+ CompilationInfo* info) {
Handle<DependentCode> codes =
- DependentCode::Insert(dep, DependentCode::kPropertyCellChangedGroup,
+ DependentCode::Insert(handle(cell->dependent_code(), info->isolate()),
+ DependentCode::kPropertyCellChangedGroup,
info->object_wrapper());
- if (*codes != dependent_code()) set_dependent_code(*codes);
+ if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes);
info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
- Handle<HeapObject>(this), info->zone());
+ cell, info->zone());
}
diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h
index e3ed08c4dc..12f2ee0e5c 100644
--- a/deps/v8/src/objects.h
+++ b/deps/v8/src/objects.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_OBJECTS_H_
#define V8_OBJECTS_H_
@@ -52,111 +29,113 @@
// Most object types in the V8 JavaScript are described in this file.
//
// Inheritance hierarchy:
-// - MaybeObject (an object or a failure)
-// - Failure (immediate for marking failed operation)
-// - Object
-// - Smi (immediate small integer)
-// - HeapObject (superclass for everything allocated in the heap)
-// - JSReceiver (suitable for property access)
-// - JSObject
-// - JSArray
-// - JSArrayBuffer
-// - JSArrayBufferView
-// - JSTypedArray
-// - JSDataView
-// - JSSet
-// - JSMap
-// - JSWeakCollection
-// - JSWeakMap
-// - JSWeakSet
-// - JSRegExp
-// - JSFunction
-// - JSGeneratorObject
-// - JSModule
-// - GlobalObject
-// - JSGlobalObject
-// - JSBuiltinsObject
-// - JSGlobalProxy
-// - JSValue
-// - JSDate
-// - JSMessageObject
-// - JSProxy
-// - JSFunctionProxy
-// - FixedArrayBase
-// - ByteArray
-// - FixedArray
-// - DescriptorArray
-// - HashTable
-// - Dictionary
-// - StringTable
-// - CompilationCacheTable
-// - CodeCacheHashTable
-// - MapCache
-// - Context
-// - JSFunctionResultCache
-// - ScopeInfo
-// - TransitionArray
-// - FixedDoubleArray
-// - ExternalArray
-// - ExternalUint8ClampedArray
-// - ExternalInt8Array
-// - ExternalUint8Array
-// - ExternalInt16Array
-// - ExternalUint16Array
-// - ExternalInt32Array
-// - ExternalUint32Array
-// - ExternalFloat32Array
-// - Name
-// - String
-// - SeqString
-// - SeqOneByteString
-// - SeqTwoByteString
-// - SlicedString
-// - ConsString
-// - ExternalString
-// - ExternalAsciiString
-// - ExternalTwoByteString
-// - InternalizedString
-// - SeqInternalizedString
-// - SeqOneByteInternalizedString
-// - SeqTwoByteInternalizedString
-// - ConsInternalizedString
-// - ExternalInternalizedString
-// - ExternalAsciiInternalizedString
-// - ExternalTwoByteInternalizedString
-// - Symbol
-// - HeapNumber
-// - Cell
-// - PropertyCell
-// - Code
-// - Map
-// - Oddball
-// - Foreign
-// - SharedFunctionInfo
-// - Struct
-// - Box
-// - DeclaredAccessorDescriptor
-// - AccessorInfo
-// - DeclaredAccessorInfo
-// - ExecutableAccessorInfo
-// - AccessorPair
-// - AccessCheckInfo
-// - InterceptorInfo
-// - CallHandlerInfo
-// - TemplateInfo
-// - FunctionTemplateInfo
-// - ObjectTemplateInfo
-// - Script
-// - SignatureInfo
-// - TypeSwitchInfo
-// - DebugInfo
-// - BreakPointInfo
-// - CodeCache
+// - Object
+// - Smi (immediate small integer)
+// - HeapObject (superclass for everything allocated in the heap)
+// - JSReceiver (suitable for property access)
+// - JSObject
+// - JSArray
+// - JSArrayBuffer
+// - JSArrayBufferView
+// - JSTypedArray
+// - JSDataView
+// - JSSet
+// - JSMap
+// - JSSetIterator
+// - JSMapIterator
+// - JSWeakCollection
+// - JSWeakMap
+// - JSWeakSet
+// - JSRegExp
+// - JSFunction
+// - JSGeneratorObject
+// - JSModule
+// - GlobalObject
+// - JSGlobalObject
+// - JSBuiltinsObject
+// - JSGlobalProxy
+// - JSValue
+// - JSDate
+// - JSMessageObject
+// - JSProxy
+// - JSFunctionProxy
+// - FixedArrayBase
+// - ByteArray
+// - FixedArray
+// - DescriptorArray
+// - HashTable
+// - Dictionary
+// - StringTable
+// - CompilationCacheTable
+// - CodeCacheHashTable
+// - MapCache
+// - OrderedHashTable
+// - OrderedHashSet
+// - OrderedHashMap
+// - Context
+// - JSFunctionResultCache
+// - ScopeInfo
+// - TransitionArray
+// - FixedDoubleArray
+// - ExternalArray
+// - ExternalUint8ClampedArray
+// - ExternalInt8Array
+// - ExternalUint8Array
+// - ExternalInt16Array
+// - ExternalUint16Array
+// - ExternalInt32Array
+// - ExternalUint32Array
+// - ExternalFloat32Array
+// - Name
+// - String
+// - SeqString
+// - SeqOneByteString
+// - SeqTwoByteString
+// - SlicedString
+// - ConsString
+// - ExternalString
+// - ExternalAsciiString
+// - ExternalTwoByteString
+// - InternalizedString
+// - SeqInternalizedString
+// - SeqOneByteInternalizedString
+// - SeqTwoByteInternalizedString
+// - ConsInternalizedString
+// - ExternalInternalizedString
+// - ExternalAsciiInternalizedString
+// - ExternalTwoByteInternalizedString
+// - Symbol
+// - HeapNumber
+// - Cell
+// - PropertyCell
+// - Code
+// - Map
+// - Oddball
+// - Foreign
+// - SharedFunctionInfo
+// - Struct
+// - Box
+// - DeclaredAccessorDescriptor
+// - AccessorInfo
+// - DeclaredAccessorInfo
+// - ExecutableAccessorInfo
+// - AccessorPair
+// - AccessCheckInfo
+// - InterceptorInfo
+// - CallHandlerInfo
+// - TemplateInfo
+// - FunctionTemplateInfo
+// - ObjectTemplateInfo
+// - Script
+// - SignatureInfo
+// - TypeSwitchInfo
+// - DebugInfo
+// - BreakPointInfo
+// - CodeCache
//
// Formats of Object*:
// Smi: [31 bit signed int] 0
// HeapObject: [32 bit direct pointer] (4 byte aligned) | 01
-// Failure: [30 bit signed int] 11
namespace v8 {
namespace internal {
@@ -355,8 +334,6 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
\
V(INTERNALIZED_STRING_TYPE) \
V(ASCII_INTERNALIZED_STRING_TYPE) \
- V(CONS_INTERNALIZED_STRING_TYPE) \
- V(CONS_ASCII_INTERNALIZED_STRING_TYPE) \
V(EXTERNAL_INTERNALIZED_STRING_TYPE) \
V(EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE) \
V(EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE) \
@@ -444,6 +421,8 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
V(JS_PROXY_TYPE) \
V(JS_SET_TYPE) \
V(JS_MAP_TYPE) \
+ V(JS_SET_ITERATOR_TYPE) \
+ V(JS_MAP_ITERATOR_TYPE) \
V(JS_WEAK_MAP_TYPE) \
V(JS_WEAK_SET_TYPE) \
V(JS_REGEXP_TYPE) \
@@ -514,14 +493,6 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
kVariableSizeSentinel, \
ascii_internalized_string, \
AsciiInternalizedString) \
- V(CONS_INTERNALIZED_STRING_TYPE, \
- ConsString::kSize, \
- cons_internalized_string, \
- ConsInternalizedString) \
- V(CONS_ASCII_INTERNALIZED_STRING_TYPE, \
- ConsString::kSize, \
- cons_ascii_internalized_string, \
- ConsAsciiInternalizedString) \
V(EXTERNAL_INTERNALIZED_STRING_TYPE, \
ExternalTwoByteString::kSize, \
external_internalized_string, \
@@ -556,7 +527,7 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
// Note that for subtle reasons related to the ordering or numerical values of
// type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST
// manually.
-#define STRUCT_LIST_ALL(V) \
+#define STRUCT_LIST(V) \
V(BOX, Box, box) \
V(DECLARED_ACCESSOR_DESCRIPTOR, \
DeclaredAccessorDescriptor, \
@@ -577,19 +548,9 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
V(CODE_CACHE, CodeCache, code_cache) \
V(POLYMORPHIC_CODE_CACHE, PolymorphicCodeCache, polymorphic_code_cache) \
V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info) \
- V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry)
-
-#ifdef ENABLE_DEBUGGER_SUPPORT
-#define STRUCT_LIST_DEBUGGER(V) \
+ V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry) \
V(DEBUG_INFO, DebugInfo, debug_info) \
V(BREAK_POINT_INFO, BreakPointInfo, break_point_info)
-#else
-#define STRUCT_LIST_DEBUGGER(V)
-#endif
-
-#define STRUCT_LIST(V) \
- STRUCT_LIST_ALL(V) \
- STRUCT_LIST_DEBUGGER(V)
// We use the full 8 bits of the instance_type field to encode heap object
// instance types. The high-order bit (bit 7) is set if the object is not a
@@ -631,7 +592,7 @@ STATIC_ASSERT(
// Use this mask to distinguish between cons and slice only after making
// sure that the string is one of the two (an indirect string).
const uint32_t kSlicedNotConsMask = kSlicedStringTag & ~kConsStringTag;
-STATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask) && kSlicedNotConsMask != 0);
+STATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask));
// If bit 7 is clear, then bit 3 indicates whether this two-byte
// string actually contains one byte data.
@@ -662,10 +623,6 @@ enum InstanceType {
| kInternalizedTag,
ASCII_INTERNALIZED_STRING_TYPE = kOneByteStringTag | kSeqStringTag
| kInternalizedTag,
- CONS_INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kConsStringTag
- | kInternalizedTag,
- CONS_ASCII_INTERNALIZED_STRING_TYPE = kOneByteStringTag | kConsStringTag
- | kInternalizedTag,
EXTERNAL_INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kExternalStringTag
| kInternalizedTag,
EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE = kOneByteStringTag
@@ -685,9 +642,9 @@ enum InstanceType {
STRING_TYPE = INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
ASCII_STRING_TYPE = ASCII_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
- CONS_STRING_TYPE = CONS_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
+ CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag | kNotInternalizedTag,
CONS_ASCII_STRING_TYPE =
- CONS_ASCII_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
+ kOneByteStringTag | kConsStringTag | kNotInternalizedTag,
SLICED_STRING_TYPE =
kTwoByteStringTag | kSlicedStringTag | kNotInternalizedTag,
@@ -768,10 +725,6 @@ enum InstanceType {
TYPE_FEEDBACK_INFO_TYPE,
ALIASED_ARGUMENTS_ENTRY_TYPE,
BOX_TYPE,
- // The following two instance types are only used when ENABLE_DEBUGGER_SUPPORT
- // is defined. However as include/v8.h contain some of the instance type
- // constants always having them avoids them getting different numbers
- // depending on whether ENABLE_DEBUGGER_SUPPORT is defined or not.
DEBUG_INFO_TYPE,
BREAK_POINT_INFO_TYPE,
@@ -779,8 +732,6 @@ enum InstanceType {
CONSTANT_POOL_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
- JS_MESSAGE_OBJECT_TYPE,
-
// All the following types are subtypes of JSReceiver, which corresponds to
// objects in the JS sense. The first and the last type in this range are
// the two forms of function. This organization enables using the same
@@ -790,6 +741,7 @@ enum InstanceType {
JS_PROXY_TYPE, // LAST_JS_PROXY_TYPE
JS_VALUE_TYPE, // FIRST_JS_OBJECT_TYPE
+ JS_MESSAGE_OBJECT_TYPE,
JS_DATE_TYPE,
JS_OBJECT_TYPE,
JS_CONTEXT_EXTENSION_OBJECT_TYPE,
@@ -804,6 +756,8 @@ enum InstanceType {
JS_DATA_VIEW_TYPE,
JS_SET_TYPE,
JS_MAP_TYPE,
+ JS_SET_ITERATOR_TYPE,
+ JS_MAP_ITERATOR_TYPE,
JS_WEAK_MAP_TYPE,
JS_WEAK_SET_TYPE,
@@ -904,7 +858,6 @@ class AllocationSiteCreationContext;
class AllocationSiteUsageContext;
class DictionaryElementsAccessor;
class ElementsAccessor;
-class Failure;
class FixedArrayBase;
class GlobalObject;
class ObjectVisitor;
@@ -930,60 +883,6 @@ template <class C> inline bool Is(Object* obj);
#define DECLARE_PRINTER(Name)
#endif
-class MaybeObject BASE_EMBEDDED {
- public:
- inline bool IsFailure();
- inline bool IsRetryAfterGC();
- inline bool IsException();
- INLINE(bool IsTheHole());
- INLINE(bool IsUninitialized());
- inline bool ToObject(Object** obj) {
- if (IsFailure()) return false;
- *obj = reinterpret_cast<Object*>(this);
- return true;
- }
- inline Failure* ToFailureUnchecked() {
- ASSERT(IsFailure());
- return reinterpret_cast<Failure*>(this);
- }
- inline Object* ToObjectUnchecked() {
- // TODO(jkummerow): Turn this back into an ASSERT when we can be certain
- // that it never fires in Release mode in the wild.
- CHECK(!IsFailure());
- return reinterpret_cast<Object*>(this);
- }
- inline Object* ToObjectChecked() {
- CHECK(!IsFailure());
- return reinterpret_cast<Object*>(this);
- }
-
- template<typename T>
- inline bool To(T** obj) {
- if (IsFailure()) return false;
- *obj = T::cast(reinterpret_cast<Object*>(this));
- return true;
- }
-
- template<typename T>
- inline bool ToHandle(Handle<T>* obj, Isolate* isolate) {
- if (IsFailure()) return false;
- *obj = handle(T::cast(reinterpret_cast<Object*>(this)), isolate);
- return true;
- }
-
-#ifdef OBJECT_PRINT
- // Prints this object with details.
- void Print();
- void Print(FILE* out);
- void PrintLn();
- void PrintLn(FILE* out);
-#endif
-#ifdef VERIFY_HEAP
- // Verifies the object.
- void Verify();
-#endif
-};
-
#define OBJECT_TYPE_LIST(V) \
V(Smi) \
@@ -1064,6 +963,8 @@ class MaybeObject BASE_EMBEDDED {
V(JSFunctionProxy) \
V(JSSet) \
V(JSMap) \
+ V(JSSetIterator) \
+ V(JSMapIterator) \
V(JSWeakCollection) \
V(JSWeakMap) \
V(JSWeakSet) \
@@ -1087,7 +988,8 @@ class MaybeObject BASE_EMBEDDED {
V(Cell) \
V(PropertyCell) \
V(ObjectHashTable) \
- V(WeakHashTable)
+ V(WeakHashTable) \
+ V(OrderedHashTable)
#define ERROR_MESSAGES_LIST(V) \
@@ -1254,6 +1156,8 @@ class MaybeObject BASE_EMBEDDED {
V(kLiveEdit, "LiveEdit") \
V(kLookupVariableInCountOperation, \
"Lookup variable in count operation") \
+ V(kMapBecameDeprecated, "Map became deprecated") \
+ V(kMapBecameUnstable, "Map became unstable") \
V(kMapIsNoLongerInEax, "Map is no longer in eax") \
V(kModuleDeclaration, "Module declaration") \
V(kModuleLiteral, "Module literal") \
@@ -1292,6 +1196,8 @@ class MaybeObject BASE_EMBEDDED {
V(kOperandIsNotAString, "Operand is not a string") \
V(kOperandIsNotSmi, "Operand is not smi") \
V(kOperandNotANumber, "Operand not a number") \
+ V(kObjectTagged, "The object is tagged") \
+ V(kObjectNotTagged, "The object is not tagged") \
V(kOptimizationDisabled, "Optimization is disabled") \
V(kOptimizedTooManyTimes, "Optimized too many times") \
V(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister, \
@@ -1385,6 +1291,7 @@ class MaybeObject BASE_EMBEDDED {
V(kUnexpectedNegativeValue, "Unexpected negative value") \
V(kUnexpectedNumberOfPreAllocatedPropertyFields, \
"Unexpected number of pre-allocated property fields") \
+ V(kUnexpectedFPCRMode, "Unexpected FPCR mode.") \
V(kUnexpectedSmi, "Unexpected smi value") \
V(kUnexpectedStringFunction, "Unexpected String function") \
V(kUnexpectedStringType, "Unexpected string type") \
@@ -1435,9 +1342,9 @@ const char* GetBailoutReason(BailoutReason reason);
// object hierarchy.
// Object does not use any virtual functions to avoid the
// allocation of the C++ vtable.
-// Since Smi and Failure are subclasses of Object no
+// Since both Smi and HeapObject are subclasses of Object no
// data members can be present in Object.
-class Object : public MaybeObject {
+class Object {
public:
// Type testing.
bool IsObject() { return true; }
@@ -1458,17 +1365,18 @@ class Object : public MaybeObject {
INLINE(bool IsSpecObject());
INLINE(bool IsSpecFunction());
+ INLINE(bool IsTemplateInfo());
bool IsCallable();
// Oddball testing.
INLINE(bool IsUndefined());
INLINE(bool IsNull());
- INLINE(bool IsTheHole()); // Shadows MaybeObject's implementation.
+ INLINE(bool IsTheHole());
+ INLINE(bool IsException());
INLINE(bool IsUninitialized());
INLINE(bool IsTrue());
INLINE(bool IsFalse());
inline bool IsArgumentsMarker();
- inline bool NonFailureIsHeapObject();
// Filler objects (fillers and free space objects).
inline bool IsFiller();
@@ -1517,8 +1425,11 @@ class Object : public MaybeObject {
return true;
}
- inline MaybeObject* AllocateNewStorageFor(Heap* heap,
- Representation representation);
+ Handle<HeapType> OptimalType(Isolate* isolate, Representation representation);
+
+ inline static Handle<Object> NewStorageFor(Isolate* isolate,
+ Handle<Object> object,
+ Representation representation);
// Returns true if the object is of the correct type to be used as a
// implementation of a JSObject's elements.
@@ -1526,77 +1437,63 @@ class Object : public MaybeObject {
inline bool HasSpecificClassOf(String* name);
- MUST_USE_RESULT MaybeObject* ToObject(Isolate* isolate); // ECMA-262 9.9.
bool BooleanValue(); // ECMA-262 9.2.
// Convert to a JSObject if needed.
// native_context is used when creating wrapper object.
- MUST_USE_RESULT MaybeObject* ToObject(Context* native_context);
+ static inline MaybeHandle<JSReceiver> ToObject(Isolate* isolate,
+ Handle<Object> object);
+ static MaybeHandle<JSReceiver> ToObject(Isolate* isolate,
+ Handle<Object> object,
+ Handle<Context> context);
// Converts this to a Smi if possible.
- // Failure is returned otherwise.
- static MUST_USE_RESULT inline Handle<Object> ToSmi(Isolate* isolate,
- Handle<Object> object);
- MUST_USE_RESULT inline MaybeObject* ToSmi();
+ static MUST_USE_RESULT inline MaybeHandle<Smi> ToSmi(Isolate* isolate,
+ Handle<Object> object);
- void Lookup(Name* name, LookupResult* result);
-
- // Property access.
- MUST_USE_RESULT inline MaybeObject* GetProperty(Name* key);
- MUST_USE_RESULT inline MaybeObject* GetProperty(
- Name* key,
- PropertyAttributes* attributes);
+ void Lookup(Handle<Name> name, LookupResult* result);
- // TODO(yangguo): this should eventually replace the non-handlified version.
- static Handle<Object> GetPropertyWithReceiver(Handle<Object> object,
- Handle<Object> receiver,
- Handle<Name> name,
- PropertyAttributes* attributes);
- MUST_USE_RESULT MaybeObject* GetPropertyWithReceiver(
- Object* receiver,
- Name* key,
+ MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithReceiver(
+ Handle<Object> object,
+ Handle<Object> receiver,
+ Handle<Name> name,
PropertyAttributes* attributes);
-
- static Handle<Object> GetProperty(Handle<Object> object,
- Handle<Name> key);
- static Handle<Object> GetProperty(Handle<Object> object,
- Handle<Object> receiver,
- LookupResult* result,
- Handle<Name> key,
- PropertyAttributes* attributes);
-
- MUST_USE_RESULT static MaybeObject* GetPropertyOrFail(
+ MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
+ Handle<Object> object,
+ Handle<Name> key);
+ MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
+ Isolate* isolate,
+ Handle<Object> object,
+ const char* key);
+ MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
+ Handle<Object> object,
+ Handle<Name> key);
+ MUST_USE_RESULT static MaybeHandle<Object> GetProperty(
Handle<Object> object,
Handle<Object> receiver,
LookupResult* result,
Handle<Name> key,
PropertyAttributes* attributes);
- MUST_USE_RESULT MaybeObject* GetProperty(Object* receiver,
- LookupResult* result,
- Name* key,
- PropertyAttributes* attributes);
-
- MUST_USE_RESULT MaybeObject* GetPropertyWithDefinedGetter(Object* receiver,
- JSReceiver* getter);
-
- static inline Handle<Object> GetElement(Isolate* isolate,
- Handle<Object> object,
- uint32_t index);
+ MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithDefinedGetter(
+ Handle<Object> object,
+ Handle<Object> receiver,
+ Handle<JSReceiver> getter);
- // For use when we know that no exception can be thrown.
- static inline Handle<Object> GetElementNoExceptionThrown(
+ MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
Isolate* isolate,
Handle<Object> object,
uint32_t index);
- static Handle<Object> GetElementWithReceiver(Isolate* isolate,
- Handle<Object> object,
- Handle<Object> receiver,
- uint32_t index);
+ MUST_USE_RESULT static MaybeHandle<Object> GetElementWithReceiver(
+ Isolate* isolate,
+ Handle<Object> object,
+ Handle<Object> receiver,
+ uint32_t index);
// Return the object's prototype (might be Heap::null_value()).
Object* GetPrototype(Isolate* isolate);
+ static Handle<Object> GetPrototype(Isolate* isolate, Handle<Object> object);
Map* GetMarkerMap(Isolate* isolate);
// Returns the permanent hash code associated with this object. May return
@@ -1624,6 +1521,7 @@ class Object : public MaybeObject {
// < the length of the string. Used to implement [] on strings.
inline bool IsStringObjectWithCharacterAt(uint32_t index);
+ DECLARE_VERIFIER(Object)
#ifdef VERIFY_HEAP
// Verify a pointer is a valid object pointer.
static void VerifyPointer(Object* p);
@@ -1643,6 +1541,14 @@ class Object : public MaybeObject {
// Layout description.
static const int kHeaderSize = 0; // Object does not take up any space.
+#ifdef OBJECT_PRINT
+ // Prints this object with details.
+ void Print();
+ void Print(FILE* out);
+ void PrintLn();
+ void PrintLn(FILE* out);
+#endif
+
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
};
@@ -1685,72 +1591,6 @@ class Smi: public Object {
};
-// Failure is used for reporting out of memory situations and
-// propagating exceptions through the runtime system. Failure objects
-// are transient and cannot occur as part of the object graph.
-//
-// Failures are a single word, encoded as follows:
-// +-------------------------+---+--+--+
-// |.........unused..........|sss|tt|11|
-// +-------------------------+---+--+--+
-// 7 6 4 32 10
-//
-//
-// The low two bits, 0-1, are the failure tag, 11. The next two bits,
-// 2-3, are a failure type tag 'tt' with possible values:
-// 00 RETRY_AFTER_GC
-// 01 EXCEPTION
-// 10 INTERNAL_ERROR
-// 11 OUT_OF_MEMORY_EXCEPTION
-//
-// The next three bits, 4-6, are an allocation space tag 'sss'. The
-// allocation space tag is 000 for all failure types except
-// RETRY_AFTER_GC. For RETRY_AFTER_GC, the possible values are the
-// allocation spaces (the encoding is found in globals.h).
-
-// Failure type tag info.
-const int kFailureTypeTagSize = 2;
-const int kFailureTypeTagMask = (1 << kFailureTypeTagSize) - 1;
-
-class Failure: public MaybeObject {
- public:
- // RuntimeStubs assumes EXCEPTION = 1 in the compiler-generated code.
- enum Type {
- RETRY_AFTER_GC = 0,
- EXCEPTION = 1, // Returning this marker tells the real exception
- // is in Isolate::pending_exception.
- INTERNAL_ERROR = 2,
- OUT_OF_MEMORY_EXCEPTION = 3
- };
-
- inline Type type() const;
-
- // Returns the space that needs to be collected for RetryAfterGC failures.
- inline AllocationSpace allocation_space() const;
-
- inline bool IsInternalError() const;
-
- static inline Failure* RetryAfterGC(AllocationSpace space);
- static inline Failure* RetryAfterGC(); // NEW_SPACE
- static inline Failure* Exception();
- static inline Failure* InternalError();
- // Casting.
- static inline Failure* cast(MaybeObject* object);
-
- // Dispatched behavior.
- void FailurePrint(FILE* out = stdout);
- void FailurePrint(StringStream* accumulator);
-
- DECLARE_VERIFIER(Failure)
-
- private:
- inline intptr_t value() const;
- static inline Failure* Construct(Type type, intptr_t value = 0);
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(Failure);
-};
-
-
// Heap objects typically have a map pointer in their first word. However,
// during GC other data (e.g. mark bits, forwarding addresses) is sometimes
// encoded in the first word. The class MapWord is an abstraction of the
@@ -1811,6 +1651,15 @@ class HeapObject: public Object {
// of primitive (non-JS) objects like strings, heap numbers etc.
inline void set_map_no_write_barrier(Map* value);
+ // Get the map using acquire load.
+ inline Map* synchronized_map();
+ inline MapWord synchronized_map_word();
+
+ // Set the map using release store
+ inline void synchronized_set_map(Map* value);
+ inline void synchronized_set_map_no_write_barrier(Map* value);
+ inline void synchronized_set_map_word(MapWord map_word);
+
// During garbage collection, the map word of a heap object does not
// necessarily contain a map pointer.
inline MapWord map_word();
@@ -1970,11 +1819,18 @@ class HeapNumber: public HeapObject {
// Layout description.
static const int kValueOffset = HeapObject::kHeaderSize;
// IEEE doubles are two 32 bit words. The first is just mantissa, the second
- // is a mixture of sign, exponent and mantissa. Our current platforms are all
- // little endian apart from non-EABI arm which is little endian with big
- // endian floating point word ordering!
+ // is a mixture of sign, exponent and mantissa. The offsets of two 32 bit
+ // words within double numbers are endian dependent and they are set
+ // accordingly.
+#if defined(V8_TARGET_LITTLE_ENDIAN)
static const int kMantissaOffset = kValueOffset;
static const int kExponentOffset = kValueOffset + 4;
+#elif defined(V8_TARGET_BIG_ENDIAN)
+ static const int kMantissaOffset = kValueOffset + 4;
+ static const int kExponentOffset = kValueOffset;
+#else
+#error Unknown byte ordering
+#endif
static const int kSize = kValueOffset + kDoubleSize;
static const uint32_t kSignMask = 0x80000000u;
@@ -2046,18 +1902,19 @@ class JSReceiver: public HeapObject {
static inline JSReceiver* cast(Object* obj);
// Implementation of [[Put]], ECMA-262 5th edition, section 8.12.5.
- static Handle<Object> SetProperty(Handle<JSReceiver> object,
- Handle<Name> key,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictMode strict_mode,
- StoreFromKeyed store_mode =
- MAY_BE_STORE_FROM_KEYED);
- static Handle<Object> SetElement(Handle<JSReceiver> object,
- uint32_t index,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictMode strict_mode);
+ MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
+ Handle<JSReceiver> object,
+ Handle<Name> key,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode,
+ StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
+ MUST_USE_RESULT static MaybeHandle<Object> SetElement(
+ Handle<JSReceiver> object,
+ uint32_t index,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode);
// Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
static inline bool HasProperty(Handle<JSReceiver> object, Handle<Name> name);
@@ -2066,12 +1923,14 @@ class JSReceiver: public HeapObject {
static inline bool HasLocalElement(Handle<JSReceiver> object, uint32_t index);
// Implementation of [[Delete]], ECMA-262 5th edition, section 8.12.7.
- static Handle<Object> DeleteProperty(Handle<JSReceiver> object,
- Handle<Name> name,
- DeleteMode mode = NORMAL_DELETION);
- static Handle<Object> DeleteElement(Handle<JSReceiver> object,
- uint32_t index,
- DeleteMode mode = NORMAL_DELETION);
+ MUST_USE_RESULT static MaybeHandle<Object> DeleteProperty(
+ Handle<JSReceiver> object,
+ Handle<Name> name,
+ DeleteMode mode = NORMAL_DELETION);
+ MUST_USE_RESULT static MaybeHandle<Object> DeleteElement(
+ Handle<JSReceiver> object,
+ uint32_t index,
+ DeleteMode mode = NORMAL_DELETION);
// Tests for the fast common case for property enumeration.
bool IsSimpleEnum();
@@ -2118,16 +1977,23 @@ class JSReceiver: public HeapObject {
// Lookup a property. If found, the result is valid and has
// detailed information.
- void LocalLookup(Name* name, LookupResult* result,
+ void LocalLookup(Handle<Name> name, LookupResult* result,
bool search_hidden_prototypes = false);
- void Lookup(Name* name, LookupResult* result);
+ void Lookup(Handle<Name> name, LookupResult* result);
- protected:
- Smi* GenerateIdentityHash();
+ enum KeyCollectionType { LOCAL_ONLY, INCLUDE_PROTOS };
- static Handle<Object> SetPropertyWithDefinedSetter(Handle<JSReceiver> object,
- Handle<JSReceiver> setter,
- Handle<Object> value);
+ // Computes the enumerable keys for a JSObject. Used for implementing
+ // "for (n in object) { }".
+ MUST_USE_RESULT static MaybeHandle<FixedArray> GetKeys(
+ Handle<JSReceiver> object,
+ KeyCollectionType type);
+
+ protected:
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithDefinedSetter(
+ Handle<JSReceiver> object,
+ Handle<JSReceiver> setter,
+ Handle<Object> value);
private:
static PropertyAttributes GetPropertyAttributeForResult(
@@ -2137,13 +2003,14 @@ class JSReceiver: public HeapObject {
Handle<Name> name,
bool continue_search);
- static Handle<Object> SetProperty(Handle<JSReceiver> receiver,
- LookupResult* result,
- Handle<Name> key,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictMode strict_mode,
- StoreFromKeyed store_from_keyed);
+ MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
+ Handle<JSReceiver> receiver,
+ LookupResult* result,
+ Handle<Name> key,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode,
+ StoreFromKeyed store_from_keyed);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
};
@@ -2151,6 +2018,10 @@ class JSReceiver: public HeapObject {
// Forward declaration for JSObject::GetOrCreateHiddenPropertiesHashTable.
class ObjectHashTable;
+// Forward declaration for JSObject::Copy.
+class AllocationSite;
+
+
// The JSObject describes real heap allocated JavaScript objects with
// properties.
// Note that the map of JSObject changes during execution to enable inline
@@ -2185,7 +2056,10 @@ class JSObject: public JSReceiver {
// arguments object.
DECL_ACCESSORS(elements, FixedArrayBase)
inline void initialize_elements();
- MUST_USE_RESULT inline MaybeObject* ResetElements();
+ static void ResetElements(Handle<JSObject> object);
+ static inline void SetMapAndElements(Handle<JSObject> object,
+ Handle<Map> map,
+ Handle<FixedArrayBase> elements);
inline ElementsKind GetElementsKind();
inline ElementsAccessor* GetElementsAccessor();
// Returns true if an object has elements of FAST_SMI_ELEMENTS ElementsKind.
@@ -2234,15 +2108,9 @@ class JSObject: public JSReceiver {
bool HasDictionaryArgumentsElements();
inline SeededNumberDictionary* element_dictionary(); // Gets slow elements.
- inline void set_map_and_elements(
- Map* map,
- FixedArrayBase* value,
- WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
-
// Requires: HasFastElements().
static Handle<FixedArray> EnsureWritableFastElements(
Handle<JSObject> object);
- MUST_USE_RESULT inline MaybeObject* EnsureWritableFastElements();
// Collects elements starting at index 0.
// Undefined values are placed after non-undefined values.
@@ -2250,17 +2118,18 @@ class JSObject: public JSReceiver {
static Handle<Object> PrepareElementsForSort(Handle<JSObject> object,
uint32_t limit);
// As PrepareElementsForSort, but only on objects where elements is
- // a dictionary, and it will stay a dictionary.
+ // a dictionary, and it will stay a dictionary. Collates undefined and
+ // unexisting elements below limit from position zero of the elements.
static Handle<Object> PrepareSlowElementsForSort(Handle<JSObject> object,
uint32_t limit);
- MUST_USE_RESULT MaybeObject* PrepareSlowElementsForSort(uint32_t limit);
- static Handle<Object> GetPropertyWithCallback(Handle<JSObject> object,
- Handle<Object> receiver,
- Handle<Object> structure,
- Handle<Name> name);
+ MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithCallback(
+ Handle<JSObject> object,
+ Handle<Object> receiver,
+ Handle<Object> structure,
+ Handle<Name> name);
- static Handle<Object> SetPropertyWithCallback(
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithCallback(
Handle<JSObject> object,
Handle<Object> structure,
Handle<Name> name,
@@ -2268,14 +2137,14 @@ class JSObject: public JSReceiver {
Handle<JSObject> holder,
StrictMode strict_mode);
- static Handle<Object> SetPropertyWithInterceptor(
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithInterceptor(
Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
StrictMode strict_mode);
- static Handle<Object> SetPropertyForResult(
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyForResult(
Handle<JSObject> object,
LookupResult* result,
Handle<Name> name,
@@ -2284,14 +2153,15 @@ class JSObject: public JSReceiver {
StrictMode strict_mode,
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
- static Handle<Object> SetLocalPropertyIgnoreAttributes(
+ MUST_USE_RESULT static MaybeHandle<Object> SetLocalPropertyIgnoreAttributes(
Handle<JSObject> object,
Handle<Name> key,
Handle<Object> value,
PropertyAttributes attributes,
ValueType value_type = OPTIMAL_REPRESENTATION,
StoreMode mode = ALLOW_AS_CONSTANT,
- ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK);
+ ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
+ StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
static inline Handle<String> ExpectedTransitionKey(Handle<Map> map);
static inline Handle<Map> ExpectedTransitionTarget(Handle<Map> map);
@@ -2310,12 +2180,14 @@ class JSObject: public JSReceiver {
static void MigrateInstance(Handle<JSObject> instance);
// Migrates the given object only if the target map is already available,
- // or returns an empty handle if such a map is not yet available.
- static Handle<Object> TryMigrateInstance(Handle<JSObject> instance);
+ // or returns false if such a map is not yet available.
+ static bool TryMigrateInstance(Handle<JSObject> instance);
// Retrieve a value in a normalized object given a lookup result.
// Handles the special representation of JS global objects.
Object* GetNormalizedProperty(const LookupResult* result);
+ static Handle<Object> GetNormalizedProperty(Handle<JSObject> object,
+ const LookupResult* result);
// Sets the property value in a normalized object given a lookup result.
// Handles the special representation of JS global objects.
@@ -2360,9 +2232,10 @@ class JSObject: public JSReceiver {
// Retrieves an AccessorPair property from the given object. Might return
// undefined if the property doesn't exist or is of a different kind.
- static Handle<Object> GetAccessor(Handle<JSObject> object,
- Handle<Name> name,
- AccessorComponent component);
+ MUST_USE_RESULT static MaybeHandle<Object> GetAccessor(
+ Handle<JSObject> object,
+ Handle<Name> name,
+ AccessorComponent component);
// Defines an AccessorPair property on the given object.
// TODO(mstarzinger): Rename to SetAccessor() and return empty handle on
@@ -2375,23 +2248,20 @@ class JSObject: public JSReceiver {
v8::AccessControl access_control = v8::DEFAULT);
// Defines an AccessorInfo property on the given object.
- static Handle<Object> SetAccessor(Handle<JSObject> object,
- Handle<AccessorInfo> info);
+ MUST_USE_RESULT static MaybeHandle<Object> SetAccessor(
+ Handle<JSObject> object,
+ Handle<AccessorInfo> info);
- static Handle<Object> GetPropertyWithInterceptor(
+ MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithInterceptor(
Handle<JSObject> object,
Handle<Object> receiver,
Handle<Name> name,
PropertyAttributes* attributes);
- static Handle<Object> GetPropertyPostInterceptor(
+ MUST_USE_RESULT static MaybeHandle<Object> GetPropertyPostInterceptor(
Handle<JSObject> object,
Handle<Object> receiver,
Handle<Name> name,
PropertyAttributes* attributes);
- MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor(
- Object* receiver,
- Name* name,
- PropertyAttributes* attributes);
// Returns true if this is an instance of an api function and has
// been modified since it was created. May give false positives.
@@ -2414,7 +2284,7 @@ class JSObject: public JSReceiver {
// Gets the value of a hidden property with the given key. Returns the hole
// if the property doesn't exist (or if called on a detached proxy),
// otherwise returns the value set for the key.
- Object* GetHiddenProperty(Name* key);
+ Object* GetHiddenProperty(Handle<Name> key);
// Deletes a hidden property. Deleting a non-existing property is
// considered successful.
static void DeleteHiddenProperty(Handle<JSObject> object,
@@ -2424,7 +2294,7 @@ class JSObject: public JSReceiver {
static void SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash);
- inline void ValidateElements();
+ static inline void ValidateElements(Handle<JSObject> object);
// Makes sure that this object can contain HeapObject as elements.
static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);
@@ -2470,21 +2340,28 @@ class JSObject: public JSReceiver {
}
// These methods do not perform access checks!
- AccessorPair* GetLocalPropertyAccessorPair(Name* name);
- AccessorPair* GetLocalElementAccessorPair(uint32_t index);
+ MUST_USE_RESULT static MaybeHandle<AccessorPair> GetLocalPropertyAccessorPair(
+ Handle<JSObject> object,
+ Handle<Name> name);
+ MUST_USE_RESULT static MaybeHandle<AccessorPair> GetLocalElementAccessorPair(
+ Handle<JSObject> object,
+ uint32_t index);
- static Handle<Object> SetFastElement(Handle<JSObject> object, uint32_t index,
- Handle<Object> value,
- StrictMode strict_mode,
- bool check_prototype);
+ MUST_USE_RESULT static MaybeHandle<Object> SetFastElement(
+ Handle<JSObject> object,
+ uint32_t index,
+ Handle<Object> value,
+ StrictMode strict_mode,
+ bool check_prototype);
- static Handle<Object> SetOwnElement(Handle<JSObject> object,
- uint32_t index,
- Handle<Object> value,
- StrictMode strict_mode);
+ MUST_USE_RESULT static MaybeHandle<Object> SetOwnElement(
+ Handle<JSObject> object,
+ uint32_t index,
+ Handle<Object> value,
+ StrictMode strict_mode);
// Empty handle is returned if the element cannot be set to the given value.
- static Handle<Object> SetElement(
+ MUST_USE_RESULT static MaybeHandle<Object> SetElement(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
@@ -2495,9 +2372,10 @@ class JSObject: public JSReceiver {
// Returns the index'th element.
// The undefined object if index is out of bounds.
- static Handle<Object> GetElementWithInterceptor(Handle<JSObject> object,
- Handle<Object> receiver,
- uint32_t index);
+ MUST_USE_RESULT static MaybeHandle<Object> GetElementWithInterceptor(
+ Handle<JSObject> object,
+ Handle<Object> receiver,
+ uint32_t index);
enum SetFastElementsCapacitySmiMode {
kAllowSmiElements,
@@ -2517,15 +2395,21 @@ class JSObject: public JSReceiver {
Handle<JSObject> object,
int capacity,
int length);
- MUST_USE_RESULT MaybeObject* SetFastDoubleElementsCapacityAndLength(
- int capacity,
- int length);
// Lookup interceptors are used for handling properties controlled by host
// objects.
inline bool HasNamedInterceptor();
inline bool HasIndexedInterceptor();
+ // Computes the enumerable keys from interceptors. Used for debug mirrors and
+ // by JSReceiver::GetKeys.
+ MUST_USE_RESULT static MaybeHandle<JSObject> GetKeysForNamedInterceptor(
+ Handle<JSObject> object,
+ Handle<JSReceiver> receiver);
+ MUST_USE_RESULT static MaybeHandle<JSObject> GetKeysForIndexedInterceptor(
+ Handle<JSObject> object,
+ Handle<JSReceiver> receiver);
+
// Support functions for v8 api (needed for correct interceptor behavior).
static bool HasRealNamedProperty(Handle<JSObject> object,
Handle<Name> key);
@@ -2544,10 +2428,11 @@ class JSObject: public JSReceiver {
inline void SetInternalField(int index, Smi* value);
// The following lookup functions skip interceptors.
- void LocalLookupRealNamedProperty(Name* name, LookupResult* result);
- void LookupRealNamedProperty(Name* name, LookupResult* result);
- void LookupRealNamedPropertyInPrototypes(Name* name, LookupResult* result);
- void LookupCallbackProperty(Name* name, LookupResult* result);
+ void LocalLookupRealNamedProperty(Handle<Name> name, LookupResult* result);
+ void LookupRealNamedProperty(Handle<Name> name, LookupResult* result);
+ void LookupRealNamedPropertyInPrototypes(Handle<Name> name,
+ LookupResult* result);
+ void LookupCallbackProperty(Handle<Name> name, LookupResult* result);
// Returns the number of properties on this object filtering out properties
// with the specified attributes (ignoring interceptors).
@@ -2576,12 +2461,6 @@ class JSObject: public JSReceiver {
// map and the ElementsKind set.
static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
ElementsKind to_kind);
- inline MUST_USE_RESULT MaybeObject* GetElementsTransitionMap(
- Isolate* isolate,
- ElementsKind elements_kind);
- MUST_USE_RESULT MaybeObject* GetElementsTransitionMapSlow(
- ElementsKind elements_kind);
-
static void TransitionElementsKind(Handle<JSObject> object,
ElementsKind to_kind);
@@ -2590,6 +2469,7 @@ class JSObject: public JSReceiver {
static void GeneralizeFieldRepresentation(Handle<JSObject> object,
int modify_index,
Representation new_representation,
+ Handle<HeapType> new_field_type,
StoreMode store_mode);
// Convert the object to use the canonical dictionary
@@ -2610,11 +2490,12 @@ class JSObject: public JSReceiver {
int unused_property_fields);
// Access fast-case object properties at index.
- MUST_USE_RESULT inline MaybeObject* FastPropertyAt(
- Representation representation,
- int index);
+ static Handle<Object> FastPropertyAt(Handle<JSObject> object,
+ Representation representation,
+ int index);
inline Object* RawFastPropertyAt(int index);
inline void FastPropertyAtPut(int index, Object* value);
+ void WriteToField(int descriptor, Object* value);
// Access to in object properties.
inline int GetInObjectPropertyOffset(int index);
@@ -2625,9 +2506,10 @@ class JSObject: public JSReceiver {
= UPDATE_WRITE_BARRIER);
// Set the object's prototype (only JSReceiver and null are allowed values).
- static Handle<Object> SetPrototype(Handle<JSObject> object,
- Handle<Object> value,
- bool skip_hidden_prototypes = false);
+ MUST_USE_RESULT static MaybeHandle<Object> SetPrototype(
+ Handle<JSObject> object,
+ Handle<Object> value,
+ bool skip_hidden_prototypes = false);
// Initializes the body after properties slot, properties slot is
// initialized by set_properties. Fill the pre-allocated fields with
@@ -2642,10 +2524,11 @@ class JSObject: public JSReceiver {
bool ReferencesObject(Object* obj);
// Disalow further properties to be added to the object.
- static Handle<Object> PreventExtensions(Handle<JSObject> object);
+ MUST_USE_RESULT static MaybeHandle<Object> PreventExtensions(
+ Handle<JSObject> object);
// ES5 Object.freeze
- static Handle<Object> Freeze(Handle<JSObject> object);
+ MUST_USE_RESULT static MaybeHandle<Object> Freeze(Handle<JSObject> object);
// Called the first time an object is observed with ES7 Object.observe.
static void SetObserved(Handle<JSObject> object);
@@ -2657,11 +2540,16 @@ class JSObject: public JSReceiver {
};
static Handle<JSObject> Copy(Handle<JSObject> object);
- static Handle<JSObject> DeepCopy(Handle<JSObject> object,
- AllocationSiteUsageContext* site_context,
- DeepCopyHints hints = kNoHints);
- static Handle<JSObject> DeepWalk(Handle<JSObject> object,
- AllocationSiteCreationContext* site_context);
+ MUST_USE_RESULT static MaybeHandle<JSObject> DeepCopy(
+ Handle<JSObject> object,
+ AllocationSiteUsageContext* site_context,
+ DeepCopyHints hints = kNoHints);
+ MUST_USE_RESULT static MaybeHandle<JSObject> DeepWalk(
+ Handle<JSObject> object,
+ AllocationSiteCreationContext* site_context);
+
+ static Handle<Object> GetDataProperty(Handle<JSObject> object,
+ Handle<Name> key);
// Casting.
static inline JSObject* cast(Object* obj);
@@ -2744,7 +2632,7 @@ class JSObject: public JSReceiver {
static const int kInitialMaxFastElementArray = 100000;
static const int kFastPropertiesSoftLimit = 12;
- static const int kMaxFastProperties = 64;
+ static const int kMaxFastProperties = 128;
static const int kMaxInstanceSize = 255 * kPointerSize;
// When extending the backing storage for property values, we increase
// its size by more than the 1 entry necessary, so sequentially adding fields
@@ -2763,6 +2651,8 @@ class JSObject: public JSReceiver {
static inline int SizeOf(Map* map, HeapObject* object);
};
+ Context* GetCreationContext();
+
// Enqueue change record for Object.observe. May cause GC.
static void EnqueueChangeRecord(Handle<JSObject> object,
const char* type,
@@ -2778,17 +2668,20 @@ class JSObject: public JSReceiver {
ElementsKind to_kind);
// Used from Object::GetProperty().
- static Handle<Object> GetPropertyWithFailedAccessCheck(
+ MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithFailedAccessCheck(
Handle<JSObject> object,
Handle<Object> receiver,
LookupResult* result,
Handle<Name> name,
PropertyAttributes* attributes);
- MUST_USE_RESULT MaybeObject* GetElementWithCallback(Object* receiver,
- Object* structure,
- uint32_t index,
- Object* holder);
+ MUST_USE_RESULT static MaybeHandle<Object> GetElementWithCallback(
+ Handle<JSObject> object,
+ Handle<Object> receiver,
+ Handle<Object> structure,
+ uint32_t index,
+ Handle<Object> holder);
+
static PropertyAttributes GetElementAttributeWithInterceptor(
Handle<JSObject> object,
Handle<JSReceiver> receiver,
@@ -2799,14 +2692,14 @@ class JSObject: public JSReceiver {
Handle<JSReceiver> receiver,
uint32_t index,
bool continue_search);
- static Handle<Object> SetElementWithCallback(
+ MUST_USE_RESULT static MaybeHandle<Object> SetElementWithCallback(
Handle<JSObject> object,
Handle<Object> structure,
uint32_t index,
Handle<Object> value,
Handle<JSObject> holder,
StrictMode strict_mode);
- static Handle<Object> SetElementWithInterceptor(
+ MUST_USE_RESULT static MaybeHandle<Object> SetElementWithInterceptor(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
@@ -2814,7 +2707,7 @@ class JSObject: public JSReceiver {
StrictMode strict_mode,
bool check_prototype,
SetPropertyMode set_mode);
- static Handle<Object> SetElementWithoutInterceptor(
+ MUST_USE_RESULT static MaybeHandle<Object> SetElementWithoutInterceptor(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
@@ -2822,13 +2715,14 @@ class JSObject: public JSReceiver {
StrictMode strict_mode,
bool check_prototype,
SetPropertyMode set_mode);
- static Handle<Object> SetElementWithCallbackSetterInPrototypes(
+ MUST_USE_RESULT
+ static MaybeHandle<Object> SetElementWithCallbackSetterInPrototypes(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
bool* found,
StrictMode strict_mode);
- static Handle<Object> SetDictionaryElement(
+ MUST_USE_RESULT static MaybeHandle<Object> SetDictionaryElement(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
@@ -2836,7 +2730,7 @@ class JSObject: public JSReceiver {
StrictMode strict_mode,
bool check_prototype,
SetPropertyMode set_mode = SET_PROPERTY);
- static Handle<Object> SetFastDoubleElement(
+ MUST_USE_RESULT static MaybeHandle<Object> SetFastDoubleElement(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
@@ -2847,26 +2741,26 @@ class JSObject: public JSReceiver {
// has a setter, invoke it and set '*done' to true. If it is found and is
// read-only, reject and set '*done' to true. Otherwise, set '*done' to
// false. Can throw and return an empty handle with '*done==true'.
- static Handle<Object> SetPropertyViaPrototypes(
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyViaPrototypes(
Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
StrictMode strict_mode,
bool* done);
- static Handle<Object> SetPropertyPostInterceptor(
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyPostInterceptor(
Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
StrictMode strict_mode);
- static Handle<Object> SetPropertyUsingTransition(
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyUsingTransition(
Handle<JSObject> object,
LookupResult* lookup,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes);
- static Handle<Object> SetPropertyWithFailedAccessCheck(
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithFailedAccessCheck(
Handle<JSObject> object,
LookupResult* result,
Handle<Name> name,
@@ -2875,7 +2769,7 @@ class JSObject: public JSReceiver {
StrictMode strict_mode);
// Add a property to an object.
- static Handle<Object> AddProperty(
+ MUST_USE_RESULT static MaybeHandle<Object> AddProperty(
Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
@@ -2887,18 +2781,6 @@ class JSObject: public JSReceiver {
StoreMode mode = ALLOW_AS_CONSTANT,
TransitionFlag flag = INSERT_TRANSITION);
- // Add a constant function property to a fast-case object.
- // This leaves a CONSTANT_TRANSITION in the old map, and
- // if it is called on a second object with this map, a
- // normal property is added instead, with a map transition.
- // This avoids the creation of many maps with the same constant
- // function, all orphaned.
- static void AddConstantProperty(Handle<JSObject> object,
- Handle<Name> name,
- Handle<Object> constant,
- PropertyAttributes attributes,
- TransitionFlag flag);
-
// Add a property to a fast-case object.
static void AddFastProperty(Handle<JSObject> object,
Handle<Name> name,
@@ -2908,31 +2790,39 @@ class JSObject: public JSReceiver {
ValueType value_type,
TransitionFlag flag);
+ static void MigrateToNewProperty(Handle<JSObject> object,
+ Handle<Map> transition,
+ Handle<Object> value);
+
// Add a property to a slow-case object.
static void AddSlowProperty(Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes);
- static Handle<Object> DeleteProperty(Handle<JSObject> object,
- Handle<Name> name,
- DeleteMode mode);
+ MUST_USE_RESULT static MaybeHandle<Object> DeleteProperty(
+ Handle<JSObject> object,
+ Handle<Name> name,
+ DeleteMode mode);
static Handle<Object> DeletePropertyPostInterceptor(Handle<JSObject> object,
Handle<Name> name,
DeleteMode mode);
- static Handle<Object> DeletePropertyWithInterceptor(Handle<JSObject> object,
- Handle<Name> name);
+ MUST_USE_RESULT static MaybeHandle<Object> DeletePropertyWithInterceptor(
+ Handle<JSObject> object,
+ Handle<Name> name);
// Deletes the named property in a normalized object.
static Handle<Object> DeleteNormalizedProperty(Handle<JSObject> object,
Handle<Name> name,
DeleteMode mode);
- static Handle<Object> DeleteElement(Handle<JSObject> object,
- uint32_t index,
- DeleteMode mode);
- static Handle<Object> DeleteElementWithInterceptor(Handle<JSObject> object,
- uint32_t index);
+ MUST_USE_RESULT static MaybeHandle<Object> DeleteElement(
+ Handle<JSObject> object,
+ uint32_t index,
+ DeleteMode mode);
+ MUST_USE_RESULT static MaybeHandle<Object> DeleteElementWithInterceptor(
+ Handle<JSObject> object,
+ uint32_t index);
bool ReferencesObjectFromElements(FixedArray* elements,
ElementsKind kind,
@@ -3008,6 +2898,10 @@ class FixedArrayBase: public HeapObject {
inline int length();
inline void set_length(int value);
+ // Get and set the length using acquire loads and release stores.
+ inline int synchronized_length();
+ inline void synchronized_set_length(int value);
+
inline static FixedArrayBase* cast(Object* object);
// Layout description.
@@ -3026,6 +2920,7 @@ class FixedArray: public FixedArrayBase {
public:
// Setter and getter for elements.
inline Object* get(int index);
+ static inline Handle<Object> get(Handle<FixedArray> array, int index);
// Setter that uses write barrier.
inline void set(int index, Object* value);
inline bool is_the_hole(int index);
@@ -3046,19 +2941,26 @@ class FixedArray: public FixedArrayBase {
// Gives access to raw memory which stores the array's data.
inline Object** data_start();
+ inline void FillWithHoles(int from, int to);
+
// Shrink length and insert filler objects.
void Shrink(int length);
- // Copy operations.
- MUST_USE_RESULT inline MaybeObject* Copy();
- MUST_USE_RESULT MaybeObject* CopySize(int new_length,
- PretenureFlag pretenure = NOT_TENURED);
+ // Copy operation.
+ static Handle<FixedArray> CopySize(Handle<FixedArray> array,
+ int new_length,
+ PretenureFlag pretenure = NOT_TENURED);
// Add the elements of a JSArray to this FixedArray.
- MUST_USE_RESULT MaybeObject* AddKeysFromJSArray(JSArray* array);
+ MUST_USE_RESULT static MaybeHandle<FixedArray> AddKeysFromArrayLike(
+ Handle<FixedArray> content,
+ Handle<JSObject> array);
- // Compute the union of this and other.
- MUST_USE_RESULT MaybeObject* UnionOfKeys(FixedArray* other);
+ // Computes the union of keys and return the result.
+ // Used for implementing "for (n in object) { }"
+ MUST_USE_RESULT static MaybeHandle<FixedArray> UnionOfKeys(
+ Handle<FixedArray> first,
+ Handle<FixedArray> second);
// Copy a sub array from the receiver to dest.
void CopyTo(int pos, FixedArray* dest, int dest_pos, int len);
@@ -3136,18 +3038,13 @@ class FixedDoubleArray: public FixedArrayBase {
// Setter and getter for elements.
inline double get_scalar(int index);
inline int64_t get_representation(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
- // TODO(ishell): Rename as get() once all usages handlified.
- inline Handle<Object> get_as_handle(int index);
+ static inline Handle<Object> get(Handle<FixedDoubleArray> array, int index);
inline void set(int index, double value);
inline void set_the_hole(int index);
// Checking for the hole.
inline bool is_the_hole(int index);
- // Copy operations
- MUST_USE_RESULT inline MaybeObject* Copy();
-
// Garbage collection support.
inline static int SizeFor(int length) {
return kHeaderSize + length * kDoubleSize;
@@ -3156,6 +3053,8 @@ class FixedDoubleArray: public FixedArrayBase {
// Gives access to raw memory which stores the array's data.
inline double* data_start();
+ inline void FillWithHoles(int from, int to);
+
// Code Generation support.
static int OffsetOfElementAt(int index) { return SizeFor(index); }
@@ -3194,6 +3093,12 @@ class FixedDoubleArray: public FixedArrayBase {
// [first_int32_index()] ... [length - 1] : 32 bit entries
class ConstantPoolArray: public FixedArrayBase {
public:
+ enum WeakObjectState {
+ NO_WEAK_OBJECTS,
+ WEAK_OBJECTS_IN_OPTIMIZED_CODE,
+ WEAK_OBJECTS_IN_IC
+ };
+
// Getters for the field storing the first index for different type entries.
inline int first_code_ptr_index();
inline int first_heap_ptr_index();
@@ -3213,6 +3118,10 @@ class ConstantPoolArray: public FixedArrayBase {
inline int32_t get_int32_entry(int index);
inline double get_int64_entry_as_double(int index);
+ // Setter and getter for weak objects state
+ inline void set_weak_object_state(WeakObjectState state);
+ inline WeakObjectState get_weak_object_state();
+
inline void set(int index, Address value);
inline void set(int index, Object* value);
inline void set(int index, int64_t value);
@@ -3220,13 +3129,10 @@ class ConstantPoolArray: public FixedArrayBase {
inline void set(int index, int32_t value);
// Set up initial state.
- inline void SetEntryCounts(int number_of_int64_entries,
- int number_of_code_ptr_entries,
- int number_of_heap_ptr_entries,
- int number_of_int32_entries);
-
- // Copy operations
- MUST_USE_RESULT inline MaybeObject* Copy();
+ inline void Init(int number_of_int64_entries,
+ int number_of_code_ptr_entries,
+ int number_of_heap_ptr_entries,
+ int number_of_int32_entries);
// Garbage collection support.
inline static int SizeFor(int number_of_int64_entries,
@@ -3266,12 +3172,16 @@ class ConstantPoolArray: public FixedArrayBase {
}
// Layout description.
- static const int kFirstCodePointerIndexOffset = FixedArray::kHeaderSize;
- static const int kFirstHeapPointerIndexOffset =
- kFirstCodePointerIndexOffset + kPointerSize;
- static const int kFirstInt32IndexOffset =
- kFirstHeapPointerIndexOffset + kPointerSize;
- static const int kFirstOffset = kFirstInt32IndexOffset + kPointerSize;
+ static const int kArrayLayoutOffset = FixedArray::kHeaderSize;
+ static const int kFirstOffset = kArrayLayoutOffset + kPointerSize;
+
+ static const int kFieldBitSize = 10;
+ static const int kMaxEntriesPerType = (1 << kFieldBitSize) - 1;
+
+ class NumberOfInt64EntriesField: public BitField<int, 0, kFieldBitSize> {};
+ class NumberOfCodePtrEntriesField: public BitField<int, 10, kFieldBitSize> {};
+ class NumberOfHeapPtrEntriesField: public BitField<int, 20, kFieldBitSize> {};
+ class WeakObjectStateField: public BitField<WeakObjectState, 30, 2> {};
// Dispatched behavior.
void ConstantPoolIterateBody(ObjectVisitor* v);
@@ -3280,10 +3190,6 @@ class ConstantPoolArray: public FixedArrayBase {
DECLARE_VERIFIER(ConstantPoolArray)
private:
- inline void set_first_code_ptr_index(int value);
- inline void set_first_heap_ptr_index(int value);
- inline void set_first_int32_index(int value);
-
inline static int OffsetAt(int number_of_int64_entries,
int number_of_code_ptr_entries,
int number_of_heap_ptr_entries,
@@ -3309,23 +3215,6 @@ class ConstantPoolArray: public FixedArrayBase {
// [2 + number of descriptors * kDescriptorSize]: start of slack
class DescriptorArray: public FixedArray {
public:
- // WhitenessWitness is used to prove that a descriptor array is white
- // (unmarked), so incremental write barriers can be skipped because the
- // marking invariant cannot be broken and slots pointing into evacuation
- // candidates will be discovered when the object is scanned. A witness is
- // always stack-allocated right after creating an array. By allocating a
- // witness, incremental marking is globally disabled. The witness is then
- // passed along wherever needed to statically prove that the array is known to
- // be white.
- class WhitenessWitness {
- public:
- inline explicit WhitenessWitness(FixedArray* array);
- inline ~WhitenessWitness();
-
- private:
- IncrementalMarking* marking_;
- };
-
// Returns true for both shared empty_descriptor_array and for smis, which the
// map uses to encode additional bit fields when the descriptor array is not
// yet used.
@@ -3396,12 +3285,14 @@ class DescriptorArray: public FixedArray {
inline Name* GetKey(int descriptor_number);
inline Object** GetKeySlot(int descriptor_number);
inline Object* GetValue(int descriptor_number);
+ inline void SetValue(int descriptor_number, Object* value);
inline Object** GetValueSlot(int descriptor_number);
inline Object** GetDescriptorStartSlot(int descriptor_number);
inline Object** GetDescriptorEndSlot(int descriptor_number);
inline PropertyDetails GetDetails(int descriptor_number);
inline PropertyType GetType(int descriptor_number);
inline int GetFieldIndex(int descriptor_number);
+ inline HeapType* GetFieldType(int descriptor_number);
inline Object* GetConstant(int descriptor_number);
inline Object* GetCallbacksObject(int descriptor_number);
inline AccessorDescriptor* GetCallbacks(int descriptor_number);
@@ -3409,59 +3300,28 @@ class DescriptorArray: public FixedArray {
inline Name* GetSortedKey(int descriptor_number);
inline int GetSortedKeyIndex(int descriptor_number);
inline void SetSortedKey(int pointer, int descriptor_number);
- inline void InitializeRepresentations(Representation representation);
inline void SetRepresentation(int descriptor_number,
Representation representation);
// Accessor for complete descriptor.
inline void Get(int descriptor_number, Descriptor* desc);
- inline void Set(int descriptor_number,
- Descriptor* desc,
- const WhitenessWitness&);
inline void Set(int descriptor_number, Descriptor* desc);
+ void Replace(int descriptor_number, Descriptor* descriptor);
// Append automatically sets the enumeration index. This should only be used
// to add descriptors in bulk at the end, followed by sorting the descriptor
// array.
- inline void Append(Descriptor* desc, const WhitenessWitness&);
inline void Append(Descriptor* desc);
- // Transfer a complete descriptor from the src descriptor array to this
- // descriptor array.
- void CopyFrom(int dst_index,
- DescriptorArray* src,
- int src_index,
- const WhitenessWitness&);
- static Handle<DescriptorArray> Merge(Handle<DescriptorArray> desc,
- int verbatim,
- int valid,
- int new_size,
- int modify_index,
- StoreMode store_mode,
- Handle<DescriptorArray> other);
- MUST_USE_RESULT MaybeObject* Merge(int verbatim,
- int valid,
- int new_size,
- int modify_index,
- StoreMode store_mode,
- DescriptorArray* other);
-
- bool IsMoreGeneralThan(int verbatim,
- int valid,
- int new_size,
- DescriptorArray* other);
-
- MUST_USE_RESULT MaybeObject* CopyUpTo(int enumeration_index) {
- return CopyUpToAddAttributes(enumeration_index, NONE);
- }
+ static Handle<DescriptorArray> CopyUpTo(Handle<DescriptorArray> desc,
+ int enumeration_index,
+ int slack = 0);
static Handle<DescriptorArray> CopyUpToAddAttributes(
Handle<DescriptorArray> desc,
int enumeration_index,
- PropertyAttributes attributes);
- MUST_USE_RESULT MaybeObject* CopyUpToAddAttributes(
- int enumeration_index,
- PropertyAttributes attributes);
+ PropertyAttributes attributes,
+ int slack = 0);
// Sort the instance descriptors by the hash codes of their keys.
void Sort();
@@ -3475,9 +3335,9 @@ class DescriptorArray: public FixedArray {
// Allocates a DescriptorArray, but returns the singleton
// empty descriptor array object if number_of_descriptors is 0.
- MUST_USE_RESULT static MaybeObject* Allocate(Isolate* isolate,
- int number_of_descriptors,
- int slack = 0);
+ static Handle<DescriptorArray> Allocate(Isolate* isolate,
+ int number_of_descriptors,
+ int slack = 0);
// Casting.
static inline DescriptorArray* cast(Object* obj);
@@ -3531,6 +3391,23 @@ class DescriptorArray: public FixedArray {
}
private:
+ // WhitenessWitness is used to prove that a descriptor array is white
+ // (unmarked), so incremental write barriers can be skipped because the
+ // marking invariant cannot be broken and slots pointing into evacuation
+ // candidates will be discovered when the object is scanned. A witness is
+ // always stack-allocated right after creating an array. By allocating a
+ // witness, incremental marking is globally disabled. The witness is then
+ // passed along wherever needed to statically prove that the array is known to
+ // be white.
+ class WhitenessWitness {
+ public:
+ inline explicit WhitenessWitness(DescriptorArray* array);
+ inline ~WhitenessWitness();
+
+ private:
+ IncrementalMarking* marking_;
+ };
+
// An entry in a DescriptorArray, represented as an (array, index) pair.
class Entry {
public:
@@ -3564,6 +3441,18 @@ class DescriptorArray: public FixedArray {
kDescriptorValue;
}
+ // Transfer a complete descriptor from the src descriptor array to this
+ // descriptor array.
+ void CopyFrom(int index,
+ DescriptorArray* src,
+ const WhitenessWitness&);
+
+ inline void Set(int descriptor_number,
+ Descriptor* desc,
+ const WhitenessWitness&);
+
+ inline void Append(Descriptor* desc, const WhitenessWitness&);
+
// Swap first and second descriptor.
inline void SwapSortedKeys(int first, int second);
@@ -3603,7 +3492,7 @@ inline int Search(T* array, Name* name, int valid_entries = 0);
// // Returns the hash value for object.
// static uint32_t HashForObject(Key key, Object* object);
// // Convert key to an object.
-// static inline Object* AsObject(Heap* heap, Key key);
+// static inline Handle<Object> AsHandle(Isolate* isolate, Key key);
// // The prefix size indicates number of elements in the beginning
// // of the backing storage.
// static const int kPrefixSize = ..;
@@ -3630,14 +3519,13 @@ class BaseShape {
}
};
-template<typename Shape, typename Key>
+template<typename Derived, typename Shape, typename Key>
class HashTable: public FixedArray {
public:
// Wrapper methods
inline uint32_t Hash(Key key) {
if (Shape::UsesSeed) {
- return Shape::SeededHash(key,
- GetHeap()->HashSeed());
+ return Shape::SeededHash(key, GetHeap()->HashSeed());
} else {
return Shape::Hash(key);
}
@@ -3645,8 +3533,7 @@ class HashTable: public FixedArray {
inline uint32_t HashForObject(Key key, Object* object) {
if (Shape::UsesSeed) {
- return Shape::SeededHashForObject(key,
- GetHeap()->HashSeed(), object);
+ return Shape::SeededHashForObject(key, GetHeap()->HashSeed(), object);
} else {
return Shape::HashForObject(key, object);
}
@@ -3682,9 +3569,9 @@ class HashTable: public FixedArray {
SetNumberOfDeletedElements(NumberOfDeletedElements() + n);
}
- // Returns a new HashTable object. Might return Failure.
- MUST_USE_RESULT static MaybeObject* Allocate(
- Heap* heap,
+ // Returns a new HashTable object.
+ MUST_USE_RESULT static Handle<Derived> New(
+ Isolate* isolate,
int at_least_space_for,
MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY,
PretenureFlag pretenure = NOT_TENURED);
@@ -3743,7 +3630,6 @@ class HashTable: public FixedArray {
void Rehash(Key key);
protected:
- friend class ObjectHashSet;
friend class ObjectHashTable;
// Find the entry at which to insert element with the given key that
@@ -3791,6 +3677,17 @@ class HashTable: public FixedArray {
return (last + number) & (size - 1);
}
+ // Attempt to shrink hash table after removal of key.
+ MUST_USE_RESULT static Handle<Derived> Shrink(Handle<Derived> table, Key key);
+
+ // Ensure enough space for n additional elements.
+ MUST_USE_RESULT static Handle<Derived> EnsureCapacity(
+ Handle<Derived> table,
+ int n,
+ Key key,
+ PretenureFlag pretenure = NOT_TENURED);
+
+ private:
// Returns _expected_ if one of entries given by the first _probe_ probes is
// equal to _expected_. Otherwise, returns the entry given by the probe
// number _probe_.
@@ -3799,16 +3696,7 @@ class HashTable: public FixedArray {
void Swap(uint32_t entry1, uint32_t entry2, WriteBarrierMode mode);
// Rehashes this hash-table into the new table.
- MUST_USE_RESULT MaybeObject* Rehash(HashTable* new_table, Key key);
-
- // Attempt to shrink hash table after removal of key.
- MUST_USE_RESULT MaybeObject* Shrink(Key key);
-
- // Ensure enough space for n additional elements.
- MUST_USE_RESULT MaybeObject* EnsureCapacity(
- int n,
- Key key,
- PretenureFlag pretenure = NOT_TENURED);
+ void Rehash(Handle<Derived> new_table, Key key);
};
@@ -3822,8 +3710,7 @@ class HashTableKey {
// Returns the hash value for object.
virtual uint32_t HashForObject(Object* key) = 0;
// Returns the key object for storing into the hash table.
- // If allocations fails a failure object is returned.
- MUST_USE_RESULT virtual MaybeObject* AsObject(Heap* heap) = 0;
+ MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) = 0;
// Required.
virtual ~HashTableKey() {}
};
@@ -3834,16 +3721,16 @@ class StringTableShape : public BaseShape<HashTableKey*> {
static inline bool IsMatch(HashTableKey* key, Object* value) {
return key->IsMatch(value);
}
+
static inline uint32_t Hash(HashTableKey* key) {
return key->Hash();
}
+
static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
return key->HashForObject(object);
}
- MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
- HashTableKey* key) {
- return key->AsObject(heap);
- }
+
+ static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
static const int kPrefixSize = 0;
static const int kEntrySize = 1;
@@ -3855,20 +3742,30 @@ class SeqOneByteString;
//
// No special elements in the prefix and the element size is 1
// because only the string itself (the key) needs to be stored.
-class StringTable: public HashTable<StringTableShape, HashTableKey*> {
- public:
- // Find string in the string table. If it is not there yet, it is
- // added. The return value is the string table which might have
- // been enlarged. If the return value is not a failure, the string
- // pointer *s is set to the string found.
- MUST_USE_RESULT MaybeObject* LookupString(String* key, Object** s);
- MUST_USE_RESULT MaybeObject* LookupKey(HashTableKey* key, Object** s);
+class StringTable: public HashTable<StringTable,
+ StringTableShape,
+ HashTableKey*> {
+ public:
+ // Find string in the string table. If it is not there yet, it is
+ // added. The return value is the string found.
+ static Handle<String> LookupString(Isolate* isolate, Handle<String> key);
+ static Handle<String> LookupKey(Isolate* isolate, HashTableKey* key);
+
+ // Tries to internalize given string and returns string handle on success
+ // or an empty handle otherwise.
+ MUST_USE_RESULT static MaybeHandle<String> InternalizeStringIfExists(
+ Isolate* isolate,
+ Handle<String> string);
// Looks up a string that is equal to the given string and returns
- // true if it is found, assigning the string to the given output
- // parameter.
- bool LookupStringIfExists(String* str, String** result);
- bool LookupTwoCharsStringIfExists(uint16_t c1, uint16_t c2, String** result);
+ // string handle if it is found, or an empty handle otherwise.
+ MUST_USE_RESULT static MaybeHandle<String> LookupStringIfExists(
+ Isolate* isolate,
+ Handle<String> str);
+ MUST_USE_RESULT static MaybeHandle<String> LookupTwoCharsStringIfExists(
+ Isolate* isolate,
+ uint16_t c1,
+ uint16_t c2);
// Casting.
static inline StringTable* cast(Object* obj);
@@ -3885,6 +3782,7 @@ class MapCacheShape : public BaseShape<HashTableKey*> {
static inline bool IsMatch(HashTableKey* key, Object* value) {
return key->IsMatch(value);
}
+
static inline uint32_t Hash(HashTableKey* key) {
return key->Hash();
}
@@ -3893,10 +3791,7 @@ class MapCacheShape : public BaseShape<HashTableKey*> {
return key->HashForObject(object);
}
- MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
- HashTableKey* key) {
- return key->AsObject(heap);
- }
+ static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
static const int kPrefixSize = 0;
static const int kEntrySize = 2;
@@ -3907,11 +3802,12 @@ class MapCacheShape : public BaseShape<HashTableKey*> {
//
// Maps keys that are a fixed array of unique names to a map.
// Used for canonicalize maps for object literals.
-class MapCache: public HashTable<MapCacheShape, HashTableKey*> {
+class MapCache: public HashTable<MapCache, MapCacheShape, HashTableKey*> {
public:
// Find cached value for a name key, otherwise return null.
Object* Lookup(FixedArray* key);
- MUST_USE_RESULT MaybeObject* Put(FixedArray* key, Map* value);
+ static Handle<MapCache> Put(
+ Handle<MapCache> map_cache, Handle<FixedArray> key, Handle<Map> value);
static inline MapCache* cast(Object* obj);
private:
@@ -3919,43 +3815,53 @@ class MapCache: public HashTable<MapCacheShape, HashTableKey*> {
};
-template <typename Shape, typename Key>
-class Dictionary: public HashTable<Shape, Key> {
+template <typename Derived, typename Shape, typename Key>
+class Dictionary: public HashTable<Derived, Shape, Key> {
+ protected:
+ typedef HashTable<Derived, Shape, Key> DerivedHashTable;
+
public:
- static inline Dictionary<Shape, Key>* cast(Object* obj) {
- return reinterpret_cast<Dictionary<Shape, Key>*>(obj);
+ static inline Dictionary* cast(Object* obj) {
+ return reinterpret_cast<Dictionary*>(obj);
}
// Returns the value at entry.
Object* ValueAt(int entry) {
- return this->get(HashTable<Shape, Key>::EntryToIndex(entry) + 1);
+ return this->get(DerivedHashTable::EntryToIndex(entry) + 1);
}
// Set the value for entry.
void ValueAtPut(int entry, Object* value) {
- this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 1, value);
+ this->set(DerivedHashTable::EntryToIndex(entry) + 1, value);
}
// Returns the property details for the property at entry.
PropertyDetails DetailsAt(int entry) {
ASSERT(entry >= 0); // Not found is -1, which is not caught by get().
return PropertyDetails(
- Smi::cast(this->get(HashTable<Shape, Key>::EntryToIndex(entry) + 2)));
+ Smi::cast(this->get(DerivedHashTable::EntryToIndex(entry) + 2)));
}
// Set the details for entry.
void DetailsAtPut(int entry, PropertyDetails value) {
- this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 2, value.AsSmi());
+ this->set(DerivedHashTable::EntryToIndex(entry) + 2, value.AsSmi());
}
// Sorting support
void CopyValuesTo(FixedArray* elements);
// Delete a property from the dictionary.
- Object* DeleteProperty(int entry, JSObject::DeleteMode mode);
+ static Handle<Object> DeleteProperty(
+ Handle<Derived> dictionary,
+ int entry,
+ JSObject::DeleteMode mode);
// Attempt to shrink the dictionary after deletion of key.
- MUST_USE_RESULT MaybeObject* Shrink(Key key);
+ MUST_USE_RESULT static inline Handle<Derived> Shrink(
+ Handle<Derived> dictionary,
+ Key key) {
+ return DerivedHashTable::Shrink(dictionary, key);
+ }
// Returns the number of elements in the dictionary filtering out properties
// with the specified attributes.
@@ -3982,17 +3888,17 @@ class Dictionary: public HashTable<Shape, Key> {
}
int NextEnumerationIndex() {
- return Smi::cast(FixedArray::get(kNextEnumerationIndexIndex))->value();
+ return Smi::cast(this->get(kNextEnumerationIndexIndex))->value();
}
- // Returns a new array for dictionary usage. Might return Failure.
- MUST_USE_RESULT static MaybeObject* Allocate(
- Heap* heap,
+ // Creates a new dictionary.
+ MUST_USE_RESULT static Handle<Derived> New(
+ Isolate* isolate,
int at_least_space_for,
PretenureFlag pretenure = NOT_TENURED);
// Ensure enough space for n additional elements.
- MUST_USE_RESULT MaybeObject* EnsureCapacity(int n, Key key);
+ static Handle<Derived> EnsureCapacity(Handle<Derived> obj, int n, Key key);
#ifdef OBJECT_PRINT
void Print(FILE* out = stdout);
@@ -4002,49 +3908,59 @@ class Dictionary: public HashTable<Shape, Key> {
// Sets the entry to (key, value) pair.
inline void SetEntry(int entry,
- Object* key,
- Object* value);
+ Handle<Object> key,
+ Handle<Object> value);
inline void SetEntry(int entry,
- Object* key,
- Object* value,
+ Handle<Object> key,
+ Handle<Object> value,
PropertyDetails details);
- MUST_USE_RESULT MaybeObject* Add(Key key,
- Object* value,
- PropertyDetails details);
+ MUST_USE_RESULT static Handle<Derived> Add(
+ Handle<Derived> dictionary,
+ Key key,
+ Handle<Object> value,
+ PropertyDetails details);
protected:
// Generic at put operation.
- MUST_USE_RESULT MaybeObject* AtPut(Key key, Object* value);
+ MUST_USE_RESULT static Handle<Derived> AtPut(
+ Handle<Derived> dictionary,
+ Key key,
+ Handle<Object> value);
// Add entry to dictionary.
- MUST_USE_RESULT MaybeObject* AddEntry(Key key,
- Object* value,
- PropertyDetails details,
- uint32_t hash);
+ static void AddEntry(
+ Handle<Derived> dictionary,
+ Key key,
+ Handle<Object> value,
+ PropertyDetails details,
+ uint32_t hash);
// Generate new enumeration indices to avoid enumeration index overflow.
- MUST_USE_RESULT MaybeObject* GenerateNewEnumerationIndices();
- static const int kMaxNumberKeyIndex =
- HashTable<Shape, Key>::kPrefixStartIndex;
+ static void GenerateNewEnumerationIndices(Handle<Derived> dictionary);
+ static const int kMaxNumberKeyIndex = DerivedHashTable::kPrefixStartIndex;
static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1;
};
-class NameDictionaryShape : public BaseShape<Name*> {
+class NameDictionaryShape : public BaseShape<Handle<Name> > {
public:
- static inline bool IsMatch(Name* key, Object* other);
- static inline uint32_t Hash(Name* key);
- static inline uint32_t HashForObject(Name* key, Object* object);
- MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
- Name* key);
+ static inline bool IsMatch(Handle<Name> key, Object* other);
+ static inline uint32_t Hash(Handle<Name> key);
+ static inline uint32_t HashForObject(Handle<Name> key, Object* object);
+ static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key);
static const int kPrefixSize = 2;
static const int kEntrySize = 3;
static const bool kIsEnumerable = true;
};
-class NameDictionary: public Dictionary<NameDictionaryShape, Name*> {
+class NameDictionary: public Dictionary<NameDictionary,
+ NameDictionaryShape,
+ Handle<Name> > {
+ typedef Dictionary<
+ NameDictionary, NameDictionaryShape, Handle<Name> > DerivedDictionary;
+
public:
static inline NameDictionary* cast(Object* obj) {
ASSERT(obj->IsDictionary());
@@ -4053,25 +3969,19 @@ class NameDictionary: public Dictionary<NameDictionaryShape, Name*> {
// Copies enumerable keys to preallocated fixed array.
void CopyEnumKeysTo(FixedArray* storage);
- static void DoGenerateNewEnumerationIndices(
+ inline static void DoGenerateNewEnumerationIndices(
Handle<NameDictionary> dictionary);
- // For transforming properties of a JSObject.
- MUST_USE_RESULT MaybeObject* TransformPropertiesToFastFor(
- JSObject* obj,
- int unused_property_fields);
-
// Find entry for key, otherwise return kNotFound. Optimized version of
// HashTable::FindEntry.
- int FindEntry(Name* key);
+ int FindEntry(Handle<Name> key);
};
class NumberDictionaryShape : public BaseShape<uint32_t> {
public:
static inline bool IsMatch(uint32_t key, Object* other);
- MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
- uint32_t key);
+ static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
static const int kEntrySize = 3;
static const bool kIsEnumerable = false;
};
@@ -4099,7 +4009,9 @@ class UnseededNumberDictionaryShape : public NumberDictionaryShape {
class SeededNumberDictionary
- : public Dictionary<SeededNumberDictionaryShape, uint32_t> {
+ : public Dictionary<SeededNumberDictionary,
+ SeededNumberDictionaryShape,
+ uint32_t> {
public:
static SeededNumberDictionary* cast(Object* obj) {
ASSERT(obj->IsDictionary());
@@ -4107,28 +4019,24 @@ class SeededNumberDictionary
}
// Type specific at put (default NONE attributes is used when adding).
- MUST_USE_RESULT MaybeObject* AtNumberPut(uint32_t key, Object* value);
+ MUST_USE_RESULT static Handle<SeededNumberDictionary> AtNumberPut(
+ Handle<SeededNumberDictionary> dictionary,
+ uint32_t key,
+ Handle<Object> value);
MUST_USE_RESULT static Handle<SeededNumberDictionary> AddNumberEntry(
Handle<SeededNumberDictionary> dictionary,
uint32_t key,
Handle<Object> value,
PropertyDetails details);
- MUST_USE_RESULT MaybeObject* AddNumberEntry(uint32_t key,
- Object* value,
- PropertyDetails details);
// Set an existing entry or add a new one if needed.
// Return the updated dictionary.
MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
Handle<SeededNumberDictionary> dictionary,
- uint32_t index,
+ uint32_t key,
Handle<Object> value,
PropertyDetails details);
- MUST_USE_RESULT MaybeObject* Set(uint32_t key,
- Object* value,
- PropertyDetails details);
-
void UpdateMaxNumberKey(uint32_t key);
// If slow elements are required we will never go back to fast-case
@@ -4152,7 +4060,9 @@ class SeededNumberDictionary
class UnseededNumberDictionary
- : public Dictionary<UnseededNumberDictionaryShape, uint32_t> {
+ : public Dictionary<UnseededNumberDictionary,
+ UnseededNumberDictionaryShape,
+ uint32_t> {
public:
static UnseededNumberDictionary* cast(Object* obj) {
ASSERT(obj->IsDictionary());
@@ -4160,87 +4070,56 @@ class UnseededNumberDictionary
}
// Type specific at put (default NONE attributes is used when adding).
- MUST_USE_RESULT MaybeObject* AtNumberPut(uint32_t key, Object* value);
- MUST_USE_RESULT MaybeObject* AddNumberEntry(uint32_t key, Object* value);
+ MUST_USE_RESULT static Handle<UnseededNumberDictionary> AtNumberPut(
+ Handle<UnseededNumberDictionary> dictionary,
+ uint32_t key,
+ Handle<Object> value);
+ MUST_USE_RESULT static Handle<UnseededNumberDictionary> AddNumberEntry(
+ Handle<UnseededNumberDictionary> dictionary,
+ uint32_t key,
+ Handle<Object> value);
// Set an existing entry or add a new one if needed.
// Return the updated dictionary.
MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set(
Handle<UnseededNumberDictionary> dictionary,
- uint32_t index,
+ uint32_t key,
Handle<Object> value);
-
- MUST_USE_RESULT MaybeObject* Set(uint32_t key, Object* value);
};
-template <int entrysize>
-class ObjectHashTableShape : public BaseShape<Object*> {
+class ObjectHashTableShape : public BaseShape<Handle<Object> > {
public:
- static inline bool IsMatch(Object* key, Object* other);
- static inline uint32_t Hash(Object* key);
- static inline uint32_t HashForObject(Object* key, Object* object);
- MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
- Object* key);
+ static inline bool IsMatch(Handle<Object> key, Object* other);
+ static inline uint32_t Hash(Handle<Object> key);
+ static inline uint32_t HashForObject(Handle<Object> key, Object* object);
+ static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
static const int kPrefixSize = 0;
- static const int kEntrySize = entrysize;
-};
-
-
-// ObjectHashSet holds keys that are arbitrary objects by using the identity
-// hash of the key for hashing purposes.
-class ObjectHashSet: public HashTable<ObjectHashTableShape<1>, Object*> {
- public:
- static inline ObjectHashSet* cast(Object* obj) {
- ASSERT(obj->IsHashTable());
- return reinterpret_cast<ObjectHashSet*>(obj);
- }
-
- // Looks up whether the given key is part of this hash set.
- bool Contains(Object* key);
-
- static Handle<ObjectHashSet> EnsureCapacity(
- Handle<ObjectHashSet> table,
- int n,
- Handle<Object> key,
- PretenureFlag pretenure = NOT_TENURED);
-
- // Attempt to shrink hash table after removal of key.
- static Handle<ObjectHashSet> Shrink(Handle<ObjectHashSet> table,
- Handle<Object> key);
-
- // Adds the given key to this hash set.
- static Handle<ObjectHashSet> Add(Handle<ObjectHashSet> table,
- Handle<Object> key);
-
- // Removes the given key from this hash set.
- static Handle<ObjectHashSet> Remove(Handle<ObjectHashSet> table,
- Handle<Object> key);
+ static const int kEntrySize = 2;
};
// ObjectHashTable maps keys that are arbitrary objects to object values by
// using the identity hash of the key for hashing purposes.
-class ObjectHashTable: public HashTable<ObjectHashTableShape<2>, Object*> {
+class ObjectHashTable: public HashTable<ObjectHashTable,
+ ObjectHashTableShape,
+ Handle<Object> > {
+ typedef HashTable<
+ ObjectHashTable, ObjectHashTableShape, Handle<Object> > DerivedHashTable;
public:
static inline ObjectHashTable* cast(Object* obj) {
ASSERT(obj->IsHashTable());
return reinterpret_cast<ObjectHashTable*>(obj);
}
- static Handle<ObjectHashTable> EnsureCapacity(
- Handle<ObjectHashTable> table,
- int n,
- Handle<Object> key,
- PretenureFlag pretenure = NOT_TENURED);
-
// Attempt to shrink hash table after removal of key.
- static Handle<ObjectHashTable> Shrink(Handle<ObjectHashTable> table,
- Handle<Object> key);
+ MUST_USE_RESULT static inline Handle<ObjectHashTable> Shrink(
+ Handle<ObjectHashTable> table,
+ Handle<Object> key);
// Looks up the value associated with the given key. The hole value is
// returned in case the key is not present.
- Object* Lookup(Object* key);
+ Object* Lookup(Handle<Object> key);
// Adds (or overwrites) the value associated with the given key. Mapping a
// key to the hole value causes removal of the whole entry.
@@ -4261,14 +4140,191 @@ class ObjectHashTable: public HashTable<ObjectHashTableShape<2>, Object*> {
};
+// OrderedHashTable is a HashTable with Object keys that preserves
+// insertion order. There are Map and Set interfaces (OrderedHashMap
+// and OrderedHashTable, below). It is meant to be used by JSMap/JSSet.
+//
+// Only Object* keys are supported, with Object::SameValue() used as the
+// equality operator and Object::GetHash() for the hash function.
+//
+// Based on the "Deterministic Hash Table" as described by Jason Orendorff at
+// https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables
+// Originally attributed to Tyler Close.
+//
+// Memory layout:
+// [0]: bucket count
+// [1]: element count
+// [2]: deleted element count
+// [3]: live iterators (doubly-linked list)
+// [4..(NumberOfBuckets() - 1)]: "hash table", where each item is an offset
+// into the data table (see below) where the
+// first item in this bucket is stored.
+// [4 + NumberOfBuckets()..length]: "data table", an array of length
+// Capacity() * kEntrySize, where the first entrysize
+// items are handled by the derived class and the
+// item at kChainOffset is another entry into the
+// data table indicating the next entry in this hash
+// bucket.
+template<class Derived, class Iterator, int entrysize>
+class OrderedHashTable: public FixedArray {
+ public:
+ // Returns an OrderedHashTable with a capacity of at least |capacity|.
+ static Handle<Derived> Allocate(
+ Isolate* isolate, int capacity, PretenureFlag pretenure = NOT_TENURED);
+
+ // Returns an OrderedHashTable (possibly |table|) with enough space
+ // to add at least one new element.
+ static Handle<Derived> EnsureGrowable(Handle<Derived> table);
+
+ // Returns an OrderedHashTable (possibly |table|) that's shrunken
+ // if possible.
+ static Handle<Derived> Shrink(Handle<Derived> table);
+
+ // Returns a new empty OrderedHashTable and updates all the iterators to
+ // point to the new table.
+ static Handle<Derived> Clear(Handle<Derived> table);
+
+ // Returns kNotFound if the key isn't present.
+ int FindEntry(Handle<Object> key);
+
+ int NumberOfElements() {
+ return Smi::cast(get(kNumberOfElementsIndex))->value();
+ }
+
+ int NumberOfDeletedElements() {
+ return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
+ }
+
+ int UsedCapacity() { return NumberOfElements() + NumberOfDeletedElements(); }
+
+ int NumberOfBuckets() {
+ return Smi::cast(get(kNumberOfBucketsIndex))->value();
+ }
+
+ Object* iterators() { return get(kIteratorsIndex); }
+
+ void set_iterators(Object* value) { set(kIteratorsIndex, value); }
+
+ // Returns the index into the data table where the new entry
+ // should be placed. The table is assumed to have enough space
+ // for a new entry.
+ int AddEntry(int hash);
+
+ // Removes the entry, and puts the_hole in entrysize pointers
+ // (leaving the hash table chain intact).
+ void RemoveEntry(int entry);
+
+ // Returns an index into |this| for the given entry.
+ int EntryToIndex(int entry) {
+ return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize);
+ }
+
+ Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
+
+ static const int kNotFound = -1;
+ static const int kMinCapacity = 4;
+
+ private:
+ static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity);
+
+ void SetNumberOfBuckets(int num) {
+ set(kNumberOfBucketsIndex, Smi::FromInt(num));
+ }
+
+ void SetNumberOfElements(int num) {
+ set(kNumberOfElementsIndex, Smi::FromInt(num));
+ }
+
+ void SetNumberOfDeletedElements(int num) {
+ set(kNumberOfDeletedElementsIndex, Smi::FromInt(num));
+ }
+
+ int Capacity() {
+ return NumberOfBuckets() * kLoadFactor;
+ }
+
+ // Returns the next entry for the given entry.
+ int ChainAt(int entry) {
+ return Smi::cast(get(EntryToIndex(entry) + kChainOffset))->value();
+ }
+
+ int HashToBucket(int hash) {
+ return hash & (NumberOfBuckets() - 1);
+ }
+
+ int HashToEntry(int hash) {
+ int bucket = HashToBucket(hash);
+ return Smi::cast(get(kHashTableStartIndex + bucket))->value();
+ }
+
+ static const int kNumberOfBucketsIndex = 0;
+ static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1;
+ static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
+ static const int kIteratorsIndex = kNumberOfDeletedElementsIndex + 1;
+ static const int kHashTableStartIndex = kIteratorsIndex + 1;
+
+ static const int kEntrySize = entrysize + 1;
+ static const int kChainOffset = entrysize;
+
+ static const int kLoadFactor = 2;
+ static const int kMaxCapacity =
+ (FixedArray::kMaxLength - kHashTableStartIndex)
+ / (1 + (kEntrySize * kLoadFactor));
+};
+
+
+class JSSetIterator;
+
+
+class OrderedHashSet: public OrderedHashTable<
+ OrderedHashSet, JSSetIterator, 1> {
+ public:
+ static OrderedHashSet* cast(Object* obj) {
+ ASSERT(obj->IsOrderedHashTable());
+ return reinterpret_cast<OrderedHashSet*>(obj);
+ }
+
+ bool Contains(Handle<Object> key);
+ static Handle<OrderedHashSet> Add(
+ Handle<OrderedHashSet> table, Handle<Object> key);
+ static Handle<OrderedHashSet> Remove(
+ Handle<OrderedHashSet> table, Handle<Object> key);
+};
+
+
+class JSMapIterator;
+
+
+class OrderedHashMap:public OrderedHashTable<
+ OrderedHashMap, JSMapIterator, 2> {
+ public:
+ static OrderedHashMap* cast(Object* obj) {
+ ASSERT(obj->IsOrderedHashTable());
+ return reinterpret_cast<OrderedHashMap*>(obj);
+ }
+
+ Object* Lookup(Handle<Object> key);
+ static Handle<OrderedHashMap> Put(
+ Handle<OrderedHashMap> table,
+ Handle<Object> key,
+ Handle<Object> value);
+
+ private:
+ Object* ValueAt(int entry) {
+ return get(EntryToIndex(entry) + kValueOffset);
+ }
+
+ static const int kValueOffset = 1;
+};
+
+
template <int entrysize>
-class WeakHashTableShape : public BaseShape<Object*> {
+class WeakHashTableShape : public BaseShape<Handle<Object> > {
public:
- static inline bool IsMatch(Object* key, Object* other);
- static inline uint32_t Hash(Object* key);
- static inline uint32_t HashForObject(Object* key, Object* object);
- MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
- Object* key);
+ static inline bool IsMatch(Handle<Object> key, Object* other);
+ static inline uint32_t Hash(Handle<Object> key);
+ static inline uint32_t HashForObject(Handle<Object> key, Object* object);
+ static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
static const int kPrefixSize = 0;
static const int kEntrySize = entrysize;
};
@@ -4277,7 +4333,11 @@ class WeakHashTableShape : public BaseShape<Object*> {
// WeakHashTable maps keys that are arbitrary objects to object values.
// It is used for the global weak hash table that maps objects
// embedded in optimized code to dependent code lists.
-class WeakHashTable: public HashTable<WeakHashTableShape<2>, Object*> {
+class WeakHashTable: public HashTable<WeakHashTable,
+ WeakHashTableShape<2>,
+ Handle<Object> > {
+ typedef HashTable<
+ WeakHashTable, WeakHashTableShape<2>, Handle<Object> > DerivedHashTable;
public:
static inline WeakHashTable* cast(Object* obj) {
ASSERT(obj->IsHashTable());
@@ -4286,11 +4346,13 @@ class WeakHashTable: public HashTable<WeakHashTableShape<2>, Object*> {
// Looks up the value associated with the given key. The hole value is
// returned in case the key is not present.
- Object* Lookup(Object* key);
+ Object* Lookup(Handle<Object> key);
// Adds (or overwrites) the value associated with the given key. Mapping a
// key to the hole value causes removal of the whole entry.
- MUST_USE_RESULT MaybeObject* Put(Object* key, Object* value);
+ MUST_USE_RESULT static Handle<WeakHashTable> Put(Handle<WeakHashTable> table,
+ Handle<Object> key,
+ Handle<Object> value);
// This function is called when heap verification is turned on.
void Zap(Object* value) {
@@ -4304,7 +4366,7 @@ class WeakHashTable: public HashTable<WeakHashTableShape<2>, Object*> {
private:
friend class MarkCompactCollector;
- void AddEntry(int entry, Object* key, Object* value);
+ void AddEntry(int entry, Handle<Object> key, Handle<Object> value);
// Returns the index to the value of an entry.
static inline int EntryToValueIndex(int entry) {
@@ -4421,6 +4483,10 @@ class ScopeInfo : public FixedArray {
// Return the initialization flag of the given context local.
InitializationFlag ContextLocalInitFlag(int var);
+ // Return true if this local was introduced by the compiler, and should not be
+ // exposed to the user in a debugger.
+ bool LocalIsSynthetic(int var);
+
// Lookup support for serialized scope info. Returns the
// the stack slot index for a given slot name if the slot is
// present; otherwise returns a value < 0. The name must be an internalized
@@ -4432,9 +4498,10 @@ class ScopeInfo : public FixedArray {
// returns a value < 0. The name must be an internalized string.
// If the slot is present and mode != NULL, sets *mode to the corresponding
// mode for that variable.
- int ContextSlotIndex(String* name,
- VariableMode* mode,
- InitializationFlag* init_flag);
+ static int ContextSlotIndex(Handle<ScopeInfo> scope_info,
+ Handle<String> name,
+ VariableMode* mode,
+ InitializationFlag* init_flag);
// Lookup support for serialized scope info. Returns the
// parameter index for a given parameter name if the parameter is present;
@@ -4560,18 +4627,27 @@ class ScopeInfo : public FixedArray {
// needs very limited number of distinct normalized maps.
class NormalizedMapCache: public FixedArray {
public:
- static const int kEntries = 64;
+ static Handle<NormalizedMapCache> New(Isolate* isolate);
- static Handle<Map> Get(Handle<NormalizedMapCache> cache,
- Handle<JSObject> object,
- PropertyNormalizationMode mode);
+ MUST_USE_RESULT MaybeHandle<Map> Get(Handle<Map> fast_map,
+ PropertyNormalizationMode mode);
+ void Set(Handle<Map> fast_map, Handle<Map> normalized_map);
void Clear();
// Casting
static inline NormalizedMapCache* cast(Object* obj);
+ static inline bool IsNormalizedMapCache(Object* obj);
DECLARE_VERIFIER(NormalizedMapCache)
+ private:
+ static const int kEntries = 64;
+
+ static inline int GetIndex(Handle<Map> map);
+
+ // The following declarations hide base class methods.
+ Object* get(int index);
+ void set(int index, Object* value);
};
@@ -4638,6 +4714,9 @@ class FreeSpace: public HeapObject {
inline int size();
inline void set_size(int value);
+ inline int nobarrier_size();
+ inline void nobarrier_set_size(int value);
+
inline int Size() { return size(); }
// Casting.
@@ -4723,13 +4802,12 @@ class ExternalUint8ClampedArray: public ExternalArray {
// Setter and getter.
inline uint8_t get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalUint8ClampedArray> array,
+ int index);
inline void set(int index, uint8_t value);
- // This accessor applies the correct conversion from Smi, HeapNumber and
- // undefined and clamps the converted value between 0 and 255.
- Object* SetValue(uint32_t index, Object* value);
-
+ // This accessor applies the correct conversion from Smi, HeapNumber
+ // and undefined and clamps the converted value between 0 and 255.
static Handle<Object> SetValue(Handle<ExternalUint8ClampedArray> array,
uint32_t index,
Handle<Object> value);
@@ -4750,17 +4828,15 @@ class ExternalInt8Array: public ExternalArray {
public:
// Setter and getter.
inline int8_t get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalInt8Array> array, int index);
inline void set(int index, int8_t value);
+ // This accessor applies the correct conversion from Smi, HeapNumber
+ // and undefined.
static Handle<Object> SetValue(Handle<ExternalInt8Array> array,
uint32_t index,
Handle<Object> value);
- // This accessor applies the correct conversion from Smi, HeapNumber
- // and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
-
// Casting.
static inline ExternalInt8Array* cast(Object* obj);
@@ -4777,17 +4853,15 @@ class ExternalUint8Array: public ExternalArray {
public:
// Setter and getter.
inline uint8_t get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalUint8Array> array, int index);
inline void set(int index, uint8_t value);
+ // This accessor applies the correct conversion from Smi, HeapNumber
+ // and undefined.
static Handle<Object> SetValue(Handle<ExternalUint8Array> array,
uint32_t index,
Handle<Object> value);
- // This accessor applies the correct conversion from Smi, HeapNumber
- // and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
-
// Casting.
static inline ExternalUint8Array* cast(Object* obj);
@@ -4804,17 +4878,15 @@ class ExternalInt16Array: public ExternalArray {
public:
// Setter and getter.
inline int16_t get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalInt16Array> array, int index);
inline void set(int index, int16_t value);
+ // This accessor applies the correct conversion from Smi, HeapNumber
+ // and undefined.
static Handle<Object> SetValue(Handle<ExternalInt16Array> array,
uint32_t index,
Handle<Object> value);
- // This accessor applies the correct conversion from Smi, HeapNumber
- // and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
-
// Casting.
static inline ExternalInt16Array* cast(Object* obj);
@@ -4831,17 +4903,16 @@ class ExternalUint16Array: public ExternalArray {
public:
// Setter and getter.
inline uint16_t get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalUint16Array> array,
+ int index);
inline void set(int index, uint16_t value);
+ // This accessor applies the correct conversion from Smi, HeapNumber
+ // and undefined.
static Handle<Object> SetValue(Handle<ExternalUint16Array> array,
uint32_t index,
Handle<Object> value);
- // This accessor applies the correct conversion from Smi, HeapNumber
- // and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
-
// Casting.
static inline ExternalUint16Array* cast(Object* obj);
@@ -4858,17 +4929,15 @@ class ExternalInt32Array: public ExternalArray {
public:
// Setter and getter.
inline int32_t get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalInt32Array> array, int index);
inline void set(int index, int32_t value);
+ // This accessor applies the correct conversion from Smi, HeapNumber
+ // and undefined.
static Handle<Object> SetValue(Handle<ExternalInt32Array> array,
uint32_t index,
Handle<Object> value);
- // This accessor applies the correct conversion from Smi, HeapNumber
- // and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
-
// Casting.
static inline ExternalInt32Array* cast(Object* obj);
@@ -4885,17 +4954,16 @@ class ExternalUint32Array: public ExternalArray {
public:
// Setter and getter.
inline uint32_t get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalUint32Array> array,
+ int index);
inline void set(int index, uint32_t value);
+ // This accessor applies the correct conversion from Smi, HeapNumber
+ // and undefined.
static Handle<Object> SetValue(Handle<ExternalUint32Array> array,
uint32_t index,
Handle<Object> value);
- // This accessor applies the correct conversion from Smi, HeapNumber
- // and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
-
// Casting.
static inline ExternalUint32Array* cast(Object* obj);
@@ -4912,17 +4980,16 @@ class ExternalFloat32Array: public ExternalArray {
public:
// Setter and getter.
inline float get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalFloat32Array> array,
+ int index);
inline void set(int index, float value);
+ // This accessor applies the correct conversion from Smi, HeapNumber
+ // and undefined.
static Handle<Object> SetValue(Handle<ExternalFloat32Array> array,
uint32_t index,
Handle<Object> value);
- // This accessor applies the correct conversion from Smi, HeapNumber
- // and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
-
// Casting.
static inline ExternalFloat32Array* cast(Object* obj);
@@ -4939,17 +5006,16 @@ class ExternalFloat64Array: public ExternalArray {
public:
// Setter and getter.
inline double get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalFloat64Array> array,
+ int index);
inline void set(int index, double value);
+ // This accessor applies the correct conversion from Smi, HeapNumber
+ // and undefined.
static Handle<Object> SetValue(Handle<ExternalFloat64Array> array,
uint32_t index,
Handle<Object> value);
- // This accessor applies the correct conversion from Smi, HeapNumber
- // and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
-
// Casting.
static inline ExternalFloat64Array* cast(Object* obj);
@@ -4999,7 +5065,7 @@ class FixedTypedArray: public FixedTypedArrayBase {
}
inline ElementType get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<FixedTypedArray> array, int index);
inline void set(int index, ElementType value);
static inline ElementType from_int(int value);
@@ -5007,8 +5073,6 @@ class FixedTypedArray: public FixedTypedArrayBase {
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
-
static Handle<Object> SetValue(Handle<FixedTypedArray<Traits> > array,
uint32_t index,
Handle<Object> value);
@@ -5026,7 +5090,8 @@ class FixedTypedArray: public FixedTypedArrayBase {
typedef elementType ElementType; \
static const InstanceType kInstanceType = FIXED_##TYPE##_ARRAY_TYPE; \
static const char* Designator() { return #type " array"; } \
- static inline MaybeObject* ToObject(Heap* heap, elementType scalar); \
+ static inline Handle<Object> ToHandle(Isolate* isolate, \
+ elementType scalar); \
static inline elementType defaultValue(); \
}; \
\
@@ -5110,9 +5175,9 @@ class DeoptimizationInputData: public FixedArray {
}
// Allocates a DeoptimizationInputData.
- MUST_USE_RESULT static MaybeObject* Allocate(Isolate* isolate,
- int deopt_entry_count,
- PretenureFlag pretenure);
+ static Handle<DeoptimizationInputData> New(Isolate* isolate,
+ int deopt_entry_count,
+ PretenureFlag pretenure);
// Casting.
static inline DeoptimizationInputData* cast(Object* obj);
@@ -5157,9 +5222,9 @@ class DeoptimizationOutputData: public FixedArray {
}
// Allocates a DeoptimizationOutputData.
- MUST_USE_RESULT static MaybeObject* Allocate(Isolate* isolate,
- int number_of_deopt_points,
- PretenureFlag pretenure);
+ static Handle<DeoptimizationOutputData> New(Isolate* isolate,
+ int number_of_deopt_points,
+ PretenureFlag pretenure);
// Casting.
static inline DeoptimizationOutputData* cast(Object* obj);
@@ -5194,6 +5259,7 @@ class Code: public HeapObject {
#define IC_KIND_LIST(V) \
V(LOAD_IC) \
V(KEYED_LOAD_IC) \
+ V(CALL_IC) \
V(STORE_IC) \
V(KEYED_STORE_IC) \
V(BINARY_OP_IC) \
@@ -5303,12 +5369,24 @@ class Code: public HeapObject {
inline bool is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; }
inline bool is_store_stub() { return kind() == STORE_IC; }
inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_IC; }
+ inline bool is_call_stub() { return kind() == CALL_IC; }
inline bool is_binary_op_stub() { return kind() == BINARY_OP_IC; }
inline bool is_compare_ic_stub() { return kind() == COMPARE_IC; }
inline bool is_compare_nil_ic_stub() { return kind() == COMPARE_NIL_IC; }
inline bool is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; }
inline bool is_keyed_stub();
inline bool is_optimized_code() { return kind() == OPTIMIZED_FUNCTION; }
+ inline bool is_weak_stub();
+ inline void mark_as_weak_stub();
+ inline bool is_invalidated_weak_stub();
+ inline void mark_as_invalidated_weak_stub();
+
+ inline bool CanBeWeakStub() {
+ Kind k = kind();
+ return (k == LOAD_IC || k == STORE_IC || k == KEYED_LOAD_IC ||
+ k == KEYED_STORE_IC || k == COMPARE_NIL_IC) &&
+ ic_state() == MONOMORPHIC;
+ }
inline void set_raw_kind_specific_flags1(int value);
inline void set_raw_kind_specific_flags2(int value);
@@ -5402,7 +5480,6 @@ class Code: public HeapObject {
// Find the first map in an IC stub.
Map* FindFirstMap();
void FindAllMaps(MapHandleList* maps);
- void FindAllTypes(TypeHandleList* types);
// Find the first handler in an IC stub.
Code* FindFirstHandler();
@@ -5523,8 +5600,6 @@ class Code: public HeapObject {
void ClearInlineCaches();
void ClearInlineCaches(Kind kind);
- void ClearTypeFeedbackInfo(Heap* heap);
-
BailoutId TranslatePcOffsetToAstId(uint32_t pc_offset);
uint32_t TranslateAstIdToPcOffset(BailoutId ast_id);
@@ -5550,7 +5625,7 @@ class Code: public HeapObject {
static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
static void MarkCodeAsExecuted(byte* sequence, Isolate* isolate);
void MakeOlder(MarkingParity);
- static bool IsYoungSequence(byte* sequence);
+ static bool IsYoungSequence(Isolate* isolate, byte* sequence);
bool IsOld();
Age GetAge();
// Gets the raw code age, including psuedo code-age values such as
@@ -5567,11 +5642,17 @@ class Code: public HeapObject {
void VerifyEmbeddedObjectsDependency();
#endif
+ inline bool CanContainWeakObjects() {
+ return is_optimized_code() || is_weak_stub();
+ }
+
inline bool IsWeakObject(Object* object) {
- return is_optimized_code() && IsWeakObjectInOptimizedCode(object);
+ return (is_optimized_code() && IsWeakObjectInOptimizedCode(object)) ||
+ (is_weak_stub() && IsWeakObjectInIC(object));
}
- inline bool IsWeakObjectInOptimizedCode(Object* object);
+ static inline bool IsWeakObjectInOptimizedCode(Object* object);
+ static inline bool IsWeakObjectInIC(Object* object);
// Max loop nesting marker used to postpose OSR. We don't take loop
// nesting that is deeper than 5 levels into account.
@@ -5634,11 +5715,17 @@ class Code: public HeapObject {
static const int kMarkedForDeoptimizationFirstBit =
kStackSlotsFirstBit + kStackSlotsBitCount + 1;
static const int kMarkedForDeoptimizationBitCount = 1;
+ static const int kWeakStubFirstBit =
+ kMarkedForDeoptimizationFirstBit + kMarkedForDeoptimizationBitCount;
+ static const int kWeakStubBitCount = 1;
+ static const int kInvalidatedWeakStubFirstBit =
+ kWeakStubFirstBit + kWeakStubBitCount;
+ static const int kInvalidatedWeakStubBitCount = 1;
STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
STATIC_ASSERT(kHasFunctionCacheFirstBit + kHasFunctionCacheBitCount <= 32);
- STATIC_ASSERT(kMarkedForDeoptimizationFirstBit +
- kMarkedForDeoptimizationBitCount <= 32);
+ STATIC_ASSERT(kInvalidatedWeakStubFirstBit +
+ kInvalidatedWeakStubBitCount <= 32);
class StackSlotsField: public BitField<int,
kStackSlotsFirstBit, kStackSlotsBitCount> {}; // NOLINT
@@ -5647,6 +5734,12 @@ class Code: public HeapObject {
class MarkedForDeoptimizationField: public BitField<bool,
kMarkedForDeoptimizationFirstBit,
kMarkedForDeoptimizationBitCount> {}; // NOLINT
+ class WeakStubField: public BitField<bool,
+ kWeakStubFirstBit,
+ kWeakStubBitCount> {}; // NOLINT
+ class InvalidatedWeakStubField: public BitField<bool,
+ kInvalidatedWeakStubFirstBit,
+ kInvalidatedWeakStubBitCount> {}; // NOLINT
// KindSpecificFlags2 layout (ALL)
static const int kIsCrankshaftedBit = 0;
@@ -5694,7 +5787,7 @@ class Code: public HeapObject {
byte* FindCodeAgeSequence();
static void GetCodeAgeAndParity(Code* code, Age* age,
MarkingParity* parity);
- static void GetCodeAgeAndParity(byte* sequence, Age* age,
+ static void GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
MarkingParity* parity);
static Code* GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity);
@@ -5731,9 +5824,14 @@ class CompilationInfo;
class DependentCode: public FixedArray {
public:
enum DependencyGroup {
+ // Group of IC stubs that weakly embed this map and depend on being
+ // invalidated when the map is garbage collected. Dependent IC stubs form
+ // a linked list. This group stores only the head of the list. This means
+ // that the number_of_entries(kWeakICGroup) is 0 or 1.
+ kWeakICGroup,
// Group of code that weakly embed this map and depend on being
// deoptimized when the map is garbage collected.
- kWeaklyEmbeddedGroup,
+ kWeakCodeGroup,
// Group of code that embed a transition to this map, and depend on being
// deoptimized when the transition is replaced by a new version.
kTransitionGroup,
@@ -5748,6 +5846,9 @@ class DependentCode: public FixedArray {
// Group of code that depends on global property values in property cells
// not being changed.
kPropertyCellChangedGroup,
+ // Group of code that omit run-time type checks for the field(s) introduced
+ // by this map.
+ kFieldTypeGroup,
// Group of code that depends on tenuring information in AllocationSites
// not being changed.
kAllocationSiteTenuringChangedGroup,
@@ -5784,6 +5885,7 @@ class DependentCode: public FixedArray {
bool MarkCodeForDeoptimization(Isolate* isolate,
DependentCode::DependencyGroup group);
+ void AddToDependentICList(Handle<Code> stub);
// The following low-level accessors should only be used by this class
// and the mark compact collector.
@@ -6000,29 +6102,16 @@ class Map: public HeapObject {
inline bool HasTransitionArray();
inline bool HasElementsTransition();
inline Map* elements_transition_map();
- MUST_USE_RESULT inline MaybeObject* set_elements_transition_map(
- Map* transitioned_map);
- inline void SetTransition(int transition_index, Map* target);
+ static Handle<TransitionArray> SetElementsTransitionMap(
+ Handle<Map> map, Handle<Map> transitioned_map);
inline Map* GetTransition(int transition_index);
+ inline int SearchTransition(Name* name);
+ inline FixedArrayBase* GetInitialElements();
- static Handle<TransitionArray> AddTransition(Handle<Map> map,
- Handle<Name> key,
- Handle<Map> target,
- SimpleTransitionFlag flag);
-
- MUST_USE_RESULT inline MaybeObject* AddTransition(Name* key,
- Map* target,
- SimpleTransitionFlag flag);
DECL_ACCESSORS(transitions, TransitionArray)
- inline void ClearTransitions(Heap* heap,
- WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
-
- void DeprecateTransitionTree();
- void DeprecateTarget(Name* key, DescriptorArray* new_descriptors);
Map* FindRootMap();
- Map* FindUpdatedMap(int verbatim, int length, DescriptorArray* descriptors);
- Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
+ Map* FindFieldOwner(int descriptor);
inline int GetInObjectPropertyOffset(int index);
@@ -6032,13 +6121,19 @@ class Map: public HeapObject {
int target_number_of_fields,
int target_inobject,
int target_unused);
- static Handle<Map> GeneralizeAllFieldRepresentations(
- Handle<Map> map,
- Representation new_representation);
+ static Handle<Map> GeneralizeAllFieldRepresentations(Handle<Map> map);
+ static Handle<HeapType> GeneralizeFieldType(Handle<HeapType> type1,
+ Handle<HeapType> type2,
+ Isolate* isolate)
+ V8_WARN_UNUSED_RESULT;
+ static void GeneralizeFieldType(Handle<Map> map,
+ int modify_index,
+ Handle<HeapType> new_field_type);
static Handle<Map> GeneralizeRepresentation(
Handle<Map> map,
int modify_index,
Representation new_representation,
+ Handle<HeapType> new_field_type,
StoreMode store_mode);
static Handle<Map> CopyGeneralizeAllRepresentations(
Handle<Map> map,
@@ -6047,14 +6142,7 @@ class Map: public HeapObject {
PropertyAttributes attributes,
const char* reason);
- void PrintGeneralization(FILE* file,
- const char* reason,
- int modify_index,
- int split,
- int descriptors,
- bool constant_to_field,
- Representation old_representation,
- Representation new_representation);
+ static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode);
// Returns the constructor name (the name (possibly, inferred name) of the
// function that was used to instantiate the object).
@@ -6100,7 +6188,7 @@ class Map: public HeapObject {
// [stub cache]: contains stubs compiled for this map.
DECL_ACCESSORS(code_cache, Object)
- // [dependent code]: list of optimized codes that have this map embedded.
+ // [dependent code]: list of optimized codes that weakly embed this map.
DECL_ACCESSORS(dependent_code, DependentCode)
// [back pointer]: points back to the parent map from which a transition
@@ -6121,13 +6209,8 @@ class Map: public HeapObject {
// 2 + 2 * i: prototype
// 3 + 2 * i: target map
inline FixedArray* GetPrototypeTransitions();
- MUST_USE_RESULT inline MaybeObject* SetPrototypeTransitions(
- FixedArray* prototype_transitions);
inline bool HasPrototypeTransitions();
- inline HeapObject* UncheckedPrototypeTransitions();
- inline TransitionArray* unchecked_transition_array();
-
static const int kProtoTransitionHeaderSize = 1;
static const int kProtoTransitionNumberOfEntriesOffset = 0;
static const int kProtoTransitionElementsPerEntry = 2;
@@ -6213,60 +6296,59 @@ class Map: public HeapObject {
// is found by re-transitioning from the root of the transition tree using the
// descriptor array of the map. Returns NULL if no updated map is found.
// This method also applies any pending migrations along the prototype chain.
- static Handle<Map> CurrentMapForDeprecated(Handle<Map> map);
+ static MaybeHandle<Map> CurrentMapForDeprecated(Handle<Map> map)
+ V8_WARN_UNUSED_RESULT;
// Same as above, but does not touch the prototype chain.
- static Handle<Map> CurrentMapForDeprecatedInternal(Handle<Map> map);
+ static MaybeHandle<Map> CurrentMapForDeprecatedInternal(Handle<Map> map)
+ V8_WARN_UNUSED_RESULT;
- static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
- MUST_USE_RESULT MaybeObject* RawCopy(int instance_size);
- MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors();
static Handle<Map> CopyDropDescriptors(Handle<Map> map);
- MUST_USE_RESULT MaybeObject* CopyDropDescriptors();
- static Handle<Map> CopyReplaceDescriptors(Handle<Map> map,
- Handle<DescriptorArray> descriptors,
- TransitionFlag flag,
- Handle<Name> name);
- MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors(
- DescriptorArray* descriptors,
- TransitionFlag flag,
- Name* name = NULL,
- SimpleTransitionFlag simple_flag = FULL_TRANSITION);
- static Handle<Map> CopyInstallDescriptors(
+ static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
+ Descriptor* descriptor,
+ TransitionFlag flag);
+ static Handle<Map> CopyReplaceDescriptor(Handle<Map> map,
+ Handle<DescriptorArray> descriptors,
+ Descriptor* descriptor,
+ int index,
+ TransitionFlag flag);
+
+ MUST_USE_RESULT static MaybeHandle<Map> CopyWithField(
Handle<Map> map,
- int new_descriptor,
- Handle<DescriptorArray> descriptors);
- MUST_USE_RESULT MaybeObject* ShareDescriptor(DescriptorArray* descriptors,
- Descriptor* descriptor);
- MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor,
- TransitionFlag flag);
- MUST_USE_RESULT MaybeObject* CopyInsertDescriptor(Descriptor* descriptor,
- TransitionFlag flag);
- MUST_USE_RESULT MaybeObject* CopyReplaceDescriptor(
- DescriptorArray* descriptors,
- Descriptor* descriptor,
- int index,
+ Handle<Name> name,
+ Handle<HeapType> type,
+ PropertyAttributes attributes,
+ Representation representation,
+ TransitionFlag flag);
+
+ MUST_USE_RESULT static MaybeHandle<Map> CopyWithConstant(
+ Handle<Map> map,
+ Handle<Name> name,
+ Handle<Object> constant,
+ PropertyAttributes attributes,
TransitionFlag flag);
- MUST_USE_RESULT MaybeObject* AsElementsKind(ElementsKind kind);
+ // Returns a new map with all transitions dropped from the given map and
+ // the ElementsKind set.
+ static Handle<Map> TransitionElementsTo(Handle<Map> map,
+ ElementsKind to_kind);
static Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind kind);
- MUST_USE_RESULT MaybeObject* CopyAsElementsKind(ElementsKind kind,
- TransitionFlag flag);
+ static Handle<Map> CopyAsElementsKind(Handle<Map> map,
+ ElementsKind kind,
+ TransitionFlag flag);
static Handle<Map> CopyForObserved(Handle<Map> map);
- static Handle<Map> CopyNormalized(Handle<Map> map,
- PropertyNormalizationMode mode,
- NormalizedMapSharingMode sharing);
+ static Handle<Map> CopyForFreeze(Handle<Map> map);
- inline void AppendDescriptor(Descriptor* desc,
- const DescriptorArray::WhitenessWitness&);
+ inline void AppendDescriptor(Descriptor* desc);
// Returns a copy of the map, with all transitions dropped from the
// instance descriptors.
static Handle<Map> Copy(Handle<Map> map);
- MUST_USE_RESULT MaybeObject* Copy();
+ static Handle<Map> Create(Handle<JSFunction> constructor,
+ int extra_inobject_properties);
// Returns the next free property index (only valid for FAST MODE).
int NextFreePropertyIndex();
@@ -6286,9 +6368,6 @@ class Map: public HeapObject {
// Casting.
static inline Map* cast(Object* obj);
- // Locate an accessor in the instance descriptor.
- AccessorDescriptor* FindAccessor(Name* name);
-
// Code cache operations.
// Clears the code cache.
@@ -6298,7 +6377,6 @@ class Map: public HeapObject {
static void UpdateCodeCache(Handle<Map> map,
Handle<Name> name,
Handle<Code> code);
- MUST_USE_RESULT MaybeObject* UpdateCodeCache(Name* name, Code* code);
// Extend the descriptor array of the map with the list of descriptors.
// In case of duplicates, the latest descriptor is used.
@@ -6325,14 +6403,6 @@ class Map: public HeapObject {
// Computes a hash value for this map, to be used in HashTables and such.
int Hash();
- bool EquivalentToForTransition(Map* other);
-
- // Compares this map to another to see if they describe equivalent objects.
- // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
- // it had exactly zero inobject properties.
- // The "shared" flags of both this map and |other| are ignored.
- bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
-
// Returns the map that this map transitions to if its elements_kind
// is changed to |elements_kind|, or NULL if no such map is cached yet.
// |safe_to_add_transitions| is set to false if adding transitions is not
@@ -6345,15 +6415,6 @@ class Map: public HeapObject {
Handle<Map> FindTransitionedMap(MapHandleList* candidates);
Map* FindTransitionedMap(MapList* candidates);
- // Zaps the contents of backing data structures. Note that the
- // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects
- // holding weak references when incremental marking is used, because it also
- // iterates over objects that are otherwise unreachable.
- // In general we only want to call these functions in release mode when
- // heap verification is turned on.
- void ZapPrototypeTransitions();
- void ZapTransitions();
-
bool CanTransition() {
// Only JSObject and subtypes have map transitions and back pointers.
STATIC_ASSERT(LAST_TYPE == LAST_JS_OBJECT_TYPE);
@@ -6374,18 +6435,17 @@ class Map: public HeapObject {
return type == JS_GLOBAL_OBJECT_TYPE || type == JS_BUILTINS_OBJECT_TYPE;
}
- // Fires when the layout of an object with a leaf map changes.
- // This includes adding transitions to the leaf map or changing
- // the descriptor array.
- inline void NotifyLeafMapLayoutChange();
-
inline bool CanOmitMapChecks();
- void AddDependentCompilationInfo(DependentCode::DependencyGroup group,
- CompilationInfo* info);
+ static void AddDependentCompilationInfo(Handle<Map> map,
+ DependentCode::DependencyGroup group,
+ CompilationInfo* info);
- void AddDependentCode(DependentCode::DependencyGroup group,
- Handle<Code> code);
+ static void AddDependentCode(Handle<Map> map,
+ DependentCode::DependencyGroup group,
+ Handle<Code> code);
+ static void AddDependentIC(Handle<Map> map,
+ Handle<Code> stub);
bool IsMapInArrayPrototypeChain();
@@ -6413,11 +6473,8 @@ class Map: public HeapObject {
// transitions are in the form of a map where the keys are prototype objects
// and the values are the maps the are transitioned to.
static const int kMaxCachedPrototypeTransitions = 256;
- static Handle<Map> GetPrototypeTransition(Handle<Map> map,
- Handle<Object> prototype);
- static Handle<Map> PutPrototypeTransition(Handle<Map> map,
- Handle<Object> prototype,
- Handle<Map> target_map);
+ static Handle<Map> TransitionToPrototype(Handle<Map> map,
+ Handle<Object> prototype);
static const int kMaxPreAllocatedPropertyFields = 255;
@@ -6501,7 +6558,81 @@ class Map: public HeapObject {
kPointerFieldsEndOffset,
kSize> BodyDescriptor;
+ // Compares this map to another to see if they describe equivalent objects.
+ // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
+ // it had exactly zero inobject properties.
+ // The "shared" flags of both this map and |other| are ignored.
+ bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
+
private:
+ bool EquivalentToForTransition(Map* other);
+ static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
+ static Handle<Map> ShareDescriptor(Handle<Map> map,
+ Handle<DescriptorArray> descriptors,
+ Descriptor* descriptor);
+ static Handle<Map> CopyInstallDescriptors(
+ Handle<Map> map,
+ int new_descriptor,
+ Handle<DescriptorArray> descriptors);
+ static Handle<Map> CopyAddDescriptor(Handle<Map> map,
+ Descriptor* descriptor,
+ TransitionFlag flag);
+ static Handle<Map> CopyReplaceDescriptors(
+ Handle<Map> map,
+ Handle<DescriptorArray> descriptors,
+ TransitionFlag flag,
+ MaybeHandle<Name> maybe_name,
+ SimpleTransitionFlag simple_flag = FULL_TRANSITION);
+
+ static Handle<Map> CopyNormalized(Handle<Map> map,
+ PropertyNormalizationMode mode,
+ NormalizedMapSharingMode sharing);
+
+ // Fires when the layout of an object with a leaf map changes.
+ // This includes adding transitions to the leaf map or changing
+ // the descriptor array.
+ inline void NotifyLeafMapLayoutChange();
+
+ static Handle<Map> TransitionElementsToSlow(Handle<Map> object,
+ ElementsKind to_kind);
+
+ // Zaps the contents of backing data structures. Note that the
+ // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects
+ // holding weak references when incremental marking is used, because it also
+ // iterates over objects that are otherwise unreachable.
+ // In general we only want to call these functions in release mode when
+ // heap verification is turned on.
+ void ZapPrototypeTransitions();
+ void ZapTransitions();
+
+ void DeprecateTransitionTree();
+ void DeprecateTarget(Name* key, DescriptorArray* new_descriptors);
+
+ Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
+
+ void UpdateDescriptor(int descriptor_number, Descriptor* desc);
+
+ void PrintGeneralization(FILE* file,
+ const char* reason,
+ int modify_index,
+ int split,
+ int descriptors,
+ bool constant_to_field,
+ Representation old_representation,
+ Representation new_representation,
+ HeapType* old_field_type,
+ HeapType* new_field_type);
+
+ static inline void SetPrototypeTransitions(
+ Handle<Map> map,
+ Handle<FixedArray> prototype_transitions);
+
+ static Handle<Map> GetPrototypeTransition(Handle<Map> map,
+ Handle<Object> prototype);
+ static Handle<Map> PutPrototypeTransition(Handle<Map> map,
+ Handle<Object> prototype,
+ Handle<Map> target_map);
+
DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
};
@@ -6619,6 +6750,22 @@ class Script: public Struct {
// resource is accessible. Otherwise, always return true.
inline bool HasValidSource();
+ // Convert code position into column number.
+ static int GetColumnNumber(Handle<Script> script, int code_pos);
+
+ // Convert code position into (zero-based) line number.
+ // The non-handlified version does not allocate, but may be much slower.
+ static int GetLineNumber(Handle<Script> script, int code_pos);
+ int GetLineNumber(int code_pos);
+
+ static Handle<Object> GetNameOrSourceURL(Handle<Script> script);
+
+ // Init line_ends array with code positions of line ends inside script source.
+ static void InitLineEnds(Handle<Script> script);
+
+ // Get the JS object wrapping the given script; create it if none exists.
+ static Handle<JSObject> GetWrapper(Handle<Script> script);
+
// Dispatched behavior.
DECLARE_PRINTER(Script)
DECLARE_VERIFIER(Script)
@@ -6640,6 +6787,8 @@ class Script: public Struct {
static const int kSize = kFlagsOffset + kPointerSize;
private:
+ int GetLineNumberWithArray(int code_pos);
+
// Bit positions in the flags field.
static const int kCompilationTypeBit = 0;
static const int kCompilationStateBit = 1;
@@ -6723,14 +6872,12 @@ class SharedFunctionInfo: public HeapObject {
// Removed a specific optimized code object from the optimized code map.
void EvictFromOptimizedCodeMap(Code* optimized_code, const char* reason);
+ void ClearTypeFeedbackInfo();
+
// Trims the optimized code map after entries have been removed.
void TrimOptimizedCodeMap(int shrink_by);
// Add a new entry to the optimized code map.
- MUST_USE_RESULT MaybeObject* AddToOptimizedCodeMap(Context* native_context,
- Code* code,
- FixedArray* literals,
- BailoutId osr_ast_id);
static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
Handle<Context> native_context,
Handle<Code> code,
@@ -6831,6 +6978,12 @@ class SharedFunctionInfo: public HeapObject {
inline int construction_count();
inline void set_construction_count(int value);
+ // [feedback_vector] - accumulates ast node feedback from full-codegen and
+ // (increasingly) from crankshafted code where sufficient feedback isn't
+ // available. Currently the field is duplicated in
+ // TypeFeedbackInfo::feedback_vector, but the allocation is done here.
+ DECL_ACCESSORS(feedback_vector, FixedArray)
+
// [initial_map]: initial map of the first function called as a constructor.
// Saved for the duration of the tracking phase.
// This is a weak link (GC resets it to undefined_value if no other live
@@ -6940,6 +7093,7 @@ class SharedFunctionInfo: public HeapObject {
inline void set_ast_node_count(int count);
inline int profiler_ticks();
+ inline void set_profiler_ticks(int ticks);
// Inline cache age is used to infer whether the function survived a context
// disposal or not. In the former case we reset the opt_count.
@@ -7111,16 +7265,14 @@ class SharedFunctionInfo: public HeapObject {
static const int kScriptOffset = kFunctionDataOffset + kPointerSize;
static const int kDebugInfoOffset = kScriptOffset + kPointerSize;
static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize;
- static const int kInitialMapOffset =
+ static const int kFeedbackVectorOffset =
kInferredNameOffset + kPointerSize;
- // ast_node_count is a Smi field. It could be grouped with another Smi field
- // into a PSEUDO_SMI_ACCESSORS pair (on x64), if one becomes available.
- static const int kAstNodeCountOffset =
- kInitialMapOffset + kPointerSize;
+ static const int kInitialMapOffset =
+ kFeedbackVectorOffset + kPointerSize;
#if V8_HOST_ARCH_32_BIT
// Smi fields.
static const int kLengthOffset =
- kAstNodeCountOffset + kPointerSize;
+ kInitialMapOffset + kPointerSize;
static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize;
static const int kExpectedNofPropertiesOffset =
kFormalParameterCountOffset + kPointerSize;
@@ -7138,9 +7290,13 @@ class SharedFunctionInfo: public HeapObject {
kCompilerHintsOffset + kPointerSize;
static const int kCountersOffset =
kOptCountAndBailoutReasonOffset + kPointerSize;
+ static const int kAstNodeCountOffset =
+ kCountersOffset + kPointerSize;
+ static const int kProfilerTicksOffset =
+ kAstNodeCountOffset + kPointerSize;
// Total size.
- static const int kSize = kCountersOffset + kPointerSize;
+ static const int kSize = kProfilerTicksOffset + kPointerSize;
#else
// The only reason to use smi fields instead of int fields
// is to allow iteration without maps decoding during
@@ -7152,7 +7308,7 @@ class SharedFunctionInfo: public HeapObject {
// word is not set and thus this word cannot be treated as pointer
// to HeapObject during old space traversal.
static const int kLengthOffset =
- kAstNodeCountOffset + kPointerSize;
+ kInitialMapOffset + kPointerSize;
static const int kFormalParameterCountOffset =
kLengthOffset + kIntSize;
@@ -7173,21 +7329,25 @@ class SharedFunctionInfo: public HeapObject {
static const int kOptCountAndBailoutReasonOffset =
kCompilerHintsOffset + kIntSize;
-
static const int kCountersOffset =
kOptCountAndBailoutReasonOffset + kIntSize;
+ static const int kAstNodeCountOffset =
+ kCountersOffset + kIntSize;
+ static const int kProfilerTicksOffset =
+ kAstNodeCountOffset + kIntSize;
+
// Total size.
- static const int kSize = kCountersOffset + kIntSize;
+ static const int kSize = kProfilerTicksOffset + kIntSize;
#endif
// The construction counter for inobject slack tracking is stored in the
// most significant byte of compiler_hints which is otherwise unused.
// Its offset depends on the endian-ness of the architecture.
-#if __BYTE_ORDER == __LITTLE_ENDIAN
+#if defined(V8_TARGET_LITTLE_ENDIAN)
static const int kConstructionCountOffset = kCompilerHintsOffset + 3;
-#elif __BYTE_ORDER == __BIG_ENDIAN
+#elif defined(V8_TARGET_BIG_ENDIAN)
static const int kConstructionCountOffset = kCompilerHintsOffset + 0;
#else
#error Unknown byte ordering
@@ -7261,12 +7421,12 @@ class SharedFunctionInfo: public HeapObject {
static const int kNativeBitWithinByte =
(kNative + kCompilerHintsSmiTagSize) % kBitsPerByte;
-#if __BYTE_ORDER == __LITTLE_ENDIAN
+#if defined(V8_TARGET_LITTLE_ENDIAN)
static const int kStrictModeByteOffset = kCompilerHintsOffset +
(kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte;
static const int kNativeByteOffset = kCompilerHintsOffset +
(kNative + kCompilerHintsSmiTagSize) / kBitsPerByte;
-#elif __BYTE_ORDER == __BIG_ENDIAN
+#elif defined(V8_TARGET_BIG_ENDIAN)
static const int kStrictModeByteOffset = kCompilerHintsOffset +
(kCompilerHintsSize - 1) -
((kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte);
@@ -7300,6 +7460,7 @@ class JSGeneratorObject: public JSObject {
// cannot be resumed.
inline int continuation();
inline void set_continuation(int continuation);
+ inline bool is_suspended();
// [operand_stack]: Saved operand stack.
DECL_ACCESSORS(operand_stack, FixedArray)
@@ -7334,7 +7495,7 @@ class JSGeneratorObject: public JSObject {
enum ResumeMode { NEXT, THROW };
// Yielding from a generator returns an object with the following inobject
- // properties. See Context::generator_result_map() for the map.
+ // properties. See Context::iterator_result_map() for the map.
static const int kResultValuePropertyIndex = 0;
static const int kResultDonePropertyIndex = 1;
static const int kResultPropertyCount = 2;
@@ -7467,7 +7628,7 @@ class JSFunction: public JSObject {
// After prototype is removed, it will not be created when accessed, and
// [[Construct]] from this function will not be allowed.
- void RemovePrototype();
+ bool RemovePrototype();
inline bool should_have_prototype();
// Accessor for this function's initial map's [[class]]
@@ -7554,6 +7715,9 @@ class JSGlobalProxy : public JSObject {
// It is null value if this object is not used by any context.
DECL_ACCESSORS(native_context, Object)
+ // [hash]: The hash code property (undefined if not initialized yet).
+ DECL_ACCESSORS(hash, Object)
+
// Casting.
static inline JSGlobalProxy* cast(Object* obj);
@@ -7565,7 +7729,8 @@ class JSGlobalProxy : public JSObject {
// Layout description.
static const int kNativeContextOffset = JSObject::kHeaderSize;
- static const int kSize = kNativeContextOffset + kPointerSize;
+ static const int kHashOffset = kNativeContextOffset + kPointerSize;
+ static const int kSize = kHashOffset + kPointerSize;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy);
@@ -7594,15 +7759,6 @@ class GlobalObject: public JSObject {
// Retrieve the property cell used to store a property.
PropertyCell* GetPropertyCell(LookupResult* result);
- // This is like GetProperty, but is used when you know the lookup won't fail
- // by throwing an exception. This is for the debug and builtins global
- // objects, where it is known which properties can be expected to be present
- // on the object.
- Object* GetPropertyNoExceptionThrown(Name* key) {
- Object* answer = GetProperty(key)->ToObjectUnchecked();
- return answer;
- }
-
// Casting.
static inline GlobalObject* cast(Object* obj);
@@ -8003,38 +8159,32 @@ class CompilationCacheShape : public BaseShape<HashTableKey*> {
return key->HashForObject(object);
}
- MUST_USE_RESULT static MaybeObject* AsObject(Heap* heap,
- HashTableKey* key) {
- return key->AsObject(heap);
- }
+ static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
static const int kPrefixSize = 0;
static const int kEntrySize = 2;
};
-class CompilationCacheTable: public HashTable<CompilationCacheShape,
+class CompilationCacheTable: public HashTable<CompilationCacheTable,
+ CompilationCacheShape,
HashTableKey*> {
public:
// Find cached value for a string key, otherwise return null.
- Object* Lookup(String* src, Context* context);
- Object* LookupEval(String* src,
- Context* context,
- StrictMode strict_mode,
- int scope_position);
- Object* LookupRegExp(String* source, JSRegExp::Flags flags);
- MUST_USE_RESULT MaybeObject* Put(String* src,
- Context* context,
- Object* value);
- MUST_USE_RESULT MaybeObject* PutEval(String* src,
- Context* context,
- SharedFunctionInfo* value,
- int scope_position);
- MUST_USE_RESULT MaybeObject* PutRegExp(String* src,
- JSRegExp::Flags flags,
- FixedArray* value);
-
- // Remove given value from cache.
+ Handle<Object> Lookup(Handle<String> src, Handle<Context> context);
+ Handle<Object> LookupEval(Handle<String> src, Handle<Context> context,
+ StrictMode strict_mode, int scope_position);
+ Handle<Object> LookupRegExp(Handle<String> source, JSRegExp::Flags flags);
+ static Handle<CompilationCacheTable> Put(
+ Handle<CompilationCacheTable> cache, Handle<String> src,
+ Handle<Context> context, Handle<Object> value);
+ static Handle<CompilationCacheTable> PutEval(
+ Handle<CompilationCacheTable> cache, Handle<String> src,
+ Handle<Context> context, Handle<SharedFunctionInfo> value,
+ int scope_position);
+ static Handle<CompilationCacheTable> PutRegExp(
+ Handle<CompilationCacheTable> cache, Handle<String> src,
+ JSRegExp::Flags flags, Handle<FixedArray> value);
void Remove(Object* value);
static inline CompilationCacheTable* cast(Object* obj);
@@ -8050,7 +8200,8 @@ class CodeCache: public Struct {
DECL_ACCESSORS(normal_type_cache, Object)
// Add the code object to the cache.
- MUST_USE_RESULT MaybeObject* Update(Name* name, Code* code);
+ static void Update(
+ Handle<CodeCache> cache, Handle<Name> name, Handle<Code> code);
// Lookup code object in the cache. Returns code object if found and undefined
// if not.
@@ -8077,8 +8228,10 @@ class CodeCache: public Struct {
static const int kSize = kNormalTypeCacheOffset + kPointerSize;
private:
- MUST_USE_RESULT MaybeObject* UpdateDefaultCache(Name* name, Code* code);
- MUST_USE_RESULT MaybeObject* UpdateNormalTypeCache(Name* name, Code* code);
+ static void UpdateDefaultCache(
+ Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code);
+ static void UpdateNormalTypeCache(
+ Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code);
Object* LookupDefaultCache(Name* name, Code::Flags flags);
Object* LookupNormalTypeCache(Name* name, Code::Flags flags);
@@ -8106,21 +8259,22 @@ class CodeCacheHashTableShape : public BaseShape<HashTableKey*> {
return key->HashForObject(object);
}
- MUST_USE_RESULT static MaybeObject* AsObject(Heap* heap,
- HashTableKey* key) {
- return key->AsObject(heap);
- }
+ static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
static const int kPrefixSize = 0;
static const int kEntrySize = 2;
};
-class CodeCacheHashTable: public HashTable<CodeCacheHashTableShape,
+class CodeCacheHashTable: public HashTable<CodeCacheHashTable,
+ CodeCacheHashTableShape,
HashTableKey*> {
public:
Object* Lookup(Name* name, Code::Flags flags);
- MUST_USE_RESULT MaybeObject* Put(Name* name, Code* code);
+ static Handle<CodeCacheHashTable> Put(
+ Handle<CodeCacheHashTable> table,
+ Handle<Name> name,
+ Handle<Code> code);
int GetIndex(Name* name, Code::Flags flags);
void RemoveByIndex(int index);
@@ -8144,9 +8298,6 @@ class PolymorphicCodeCache: public Struct {
Code::Flags flags,
Handle<Code> code);
- MUST_USE_RESULT MaybeObject* Update(MapHandleList* maps,
- Code::Flags flags,
- Code* code);
// Returns an undefined value if the entry is not found.
Handle<Object> Lookup(MapHandleList* maps, Code::Flags flags);
@@ -8166,13 +8317,17 @@ class PolymorphicCodeCache: public Struct {
class PolymorphicCodeCacheHashTable
- : public HashTable<CodeCacheHashTableShape, HashTableKey*> {
+ : public HashTable<PolymorphicCodeCacheHashTable,
+ CodeCacheHashTableShape,
+ HashTableKey*> {
public:
Object* Lookup(MapHandleList* maps, int code_kind);
- MUST_USE_RESULT MaybeObject* Put(MapHandleList* maps,
- int code_kind,
- Code* code);
+ static Handle<PolymorphicCodeCacheHashTable> Put(
+ Handle<PolymorphicCodeCacheHashTable> hash_table,
+ MapHandleList* maps,
+ int code_kind,
+ Handle<Code> code);
static inline PolymorphicCodeCacheHashTable* cast(Object* obj);
@@ -8198,7 +8353,6 @@ class TypeFeedbackInfo: public Struct {
inline void set_inlined_type_change_checksum(int checksum);
inline bool matches_inlined_type_change_checksum(int checksum);
- DECL_ACCESSORS(feedback_vector, FixedArray)
static inline TypeFeedbackInfo* cast(Object* obj);
@@ -8208,10 +8362,9 @@ class TypeFeedbackInfo: public Struct {
static const int kStorage1Offset = HeapObject::kHeaderSize;
static const int kStorage2Offset = kStorage1Offset + kPointerSize;
- static const int kFeedbackVectorOffset =
- kStorage2Offset + kPointerSize;
- static const int kSize = kFeedbackVectorOffset + kPointerSize;
+ static const int kSize = kStorage2Offset + kPointerSize;
+ // TODO(mvstanton): move these sentinel declarations to shared function info.
// The object that indicates an uninitialized cache.
static inline Handle<Object> UninitializedSentinel(Isolate* isolate);
@@ -8227,9 +8380,6 @@ class TypeFeedbackInfo: public Struct {
// garbage collection (e.g., for patching the cache).
static inline Object* RawUninitializedSentinel(Heap* heap);
- static const int kForInFastCaseMarker = 0;
- static const int kForInSlowCaseMarker = 1;
-
private:
static const int kTypeChangeChecksumBits = 7;
@@ -8614,6 +8764,7 @@ class Name: public HeapObject {
// Equality operations.
inline bool Equals(Name* other);
+ inline static bool Equals(Handle<Name> one, Handle<Name> two);
// Conversion.
inline bool AsArrayIndex(uint32_t* index);
@@ -8750,28 +8901,37 @@ class String: public Name {
// true.
Vector<const uint8_t> ToOneByteVector() {
ASSERT_EQ(ASCII, state_);
- return buffer_;
+ return Vector<const uint8_t>(onebyte_start, length_);
}
// Return the two-byte content of the string. Only use if IsTwoByte()
// returns true.
Vector<const uc16> ToUC16Vector() {
ASSERT_EQ(TWO_BYTE, state_);
- return Vector<const uc16>::cast(buffer_);
+ return Vector<const uc16>(twobyte_start, length_);
+ }
+
+ uc16 Get(int i) {
+ ASSERT(i < length_);
+ ASSERT(state_ != NON_FLAT);
+ if (state_ == ASCII) return onebyte_start[i];
+ return twobyte_start[i];
}
private:
enum State { NON_FLAT, ASCII, TWO_BYTE };
// Constructors only used by String::GetFlatContent().
- explicit FlatContent(Vector<const uint8_t> chars)
- : buffer_(chars),
- state_(ASCII) { }
- explicit FlatContent(Vector<const uc16> chars)
- : buffer_(Vector<const byte>::cast(chars)),
- state_(TWO_BYTE) { }
- FlatContent() : buffer_(), state_(NON_FLAT) { }
-
- Vector<const uint8_t> buffer_;
+ explicit FlatContent(const uint8_t* start, int length)
+ : onebyte_start(start), length_(length), state_(ASCII) { }
+ explicit FlatContent(const uc16* start, int length)
+ : twobyte_start(start), length_(length), state_(TWO_BYTE) { }
+ FlatContent() : onebyte_start(NULL), length_(0), state_(NON_FLAT) { }
+
+ union {
+ const uint8_t* onebyte_start;
+ const uc16* twobyte_start;
+ };
+ int length_;
State state_;
friend class String;
@@ -8781,6 +8941,11 @@ class String: public Name {
inline int length();
inline void set_length(int value);
+ // Get and set the length of the string using acquire loads and release
+ // stores.
+ inline int synchronized_length();
+ inline void synchronized_set_length(int value);
+
// Returns whether this string has only ASCII chars, i.e. all of them can
// be ASCII encoded. This might be the case even if the string is
// two-byte. Such strings may appear when the embedder prefers
@@ -8804,7 +8969,7 @@ class String: public Name {
// to this method are not efficient unless the string is flat.
INLINE(uint16_t Get(int index));
- // Try to flatten the string. Checks first inline to see if it is
+ // Flattens the string. Checks first inline to see if it is
// necessary. Does nothing if the string is not a cons string.
// Flattening allocates a sequential string with the same data as
// the given string and mutates the cons string to a degenerate
@@ -8816,15 +8981,9 @@ class String: public Name {
//
// Degenerate cons strings are handled specially by the garbage
// collector (see IsShortcutCandidate).
- //
- // Use FlattenString from Handles.cc to flatten even in case an
- // allocation failure happens.
- inline MaybeObject* TryFlatten(PretenureFlag pretenure = NOT_TENURED);
- // Convenience function. Has exactly the same behavior as
- // TryFlatten(), except in the case of failure returns the original
- // string.
- inline String* TryFlattenGetString(PretenureFlag pretenure = NOT_TENURED);
+ static inline Handle<String> Flatten(Handle<String> string,
+ PretenureFlag pretenure = NOT_TENURED);
// Tries to return the content of a flat string as a structure holding either
// a flat vector of char or of uc16.
@@ -8843,6 +9002,7 @@ class String: public Name {
// String equality operations.
inline bool Equals(String* other);
+ inline static bool Equals(Handle<String> one, Handle<String> two);
bool IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match = false);
bool IsOneByteEqualTo(Vector<const uint8_t> str);
bool IsTwoByteEqualTo(Vector<const uc16> str);
@@ -8914,6 +9074,7 @@ class String: public Name {
static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar;
static const int kMaxUtf16CodeUnit = 0xffff;
+ static const uint32_t kMaxUtf16CodeUnitU = kMaxUtf16CodeUnit;
// Value of hash field containing computed hash equal to zero.
static const int kEmptyStringHash = kIsNotArrayIndexMask;
@@ -8986,42 +9147,26 @@ class String: public Name {
return NonOneByteStart(chars, length) >= length;
}
- // TODO(dcarney): Replace all instances of this with VisitFlat.
- template<class Visitor, class ConsOp>
- static inline void Visit(String* string,
- unsigned offset,
- Visitor& visitor,
- ConsOp& cons_op,
- int32_t type,
- unsigned length);
-
template<class Visitor>
static inline ConsString* VisitFlat(Visitor* visitor,
String* string,
- int offset,
- int length,
- int32_t type);
+ int offset = 0);
- template<class Visitor>
- static inline ConsString* VisitFlat(Visitor* visitor,
- String* string,
- int offset = 0) {
- int32_t type = string->map()->instance_type();
- return VisitFlat(visitor, string, offset, string->length(), type);
- }
+ static Handle<FixedArray> CalculateLineEnds(Handle<String> string,
+ bool include_ending_line);
private:
friend class Name;
- // Try to flatten the top level ConsString that is hiding behind this
- // string. This is a no-op unless the string is a ConsString. Flatten
- // mutates the ConsString and might return a failure.
- MUST_USE_RESULT MaybeObject* SlowTryFlatten(PretenureFlag pretenure);
+ static Handle<String> SlowFlatten(Handle<ConsString> cons,
+ PretenureFlag tenure);
// Slow case of String::Equals. This implementation works on any strings
// but it is most efficient on strings that are almost flat.
bool SlowEquals(String* other);
+ static bool SlowEquals(Handle<String> one, Handle<String> two);
+
// Slow case of AsArrayIndex.
bool SlowAsArrayIndex(uint32_t* index);
@@ -9391,57 +9536,63 @@ class ConsStringNullOp {
// This maintains an off-stack representation of the stack frames required
// to traverse a ConsString, allowing an entirely iterative and restartable
// traversal of the entire string
-// Note: this class is not GC-safe.
class ConsStringIteratorOp {
public:
inline ConsStringIteratorOp() {}
- String* Operate(String* string,
- unsigned* offset_out,
- int32_t* type_out,
- unsigned* length_out);
- inline String* ContinueOperation(int32_t* type_out, unsigned* length_out);
- inline void Reset();
- inline bool HasMore();
+ inline ConsStringIteratorOp(ConsString* cons_string, int offset = 0) {
+ Reset(cons_string, offset);
+ }
+ inline void Reset(ConsString* cons_string, int offset = 0) {
+ depth_ = 0;
+ // Next will always return NULL.
+ if (cons_string == NULL) return;
+ Initialize(cons_string, offset);
+ }
+ // Returns NULL when complete.
+ inline String* Next(int* offset_out) {
+ *offset_out = 0;
+ if (depth_ == 0) return NULL;
+ return Continue(offset_out);
+ }
private:
- // TODO(dcarney): Templatize this out for different stack sizes.
- static const unsigned kStackSize = 32;
+ static const int kStackSize = 32;
// Use a mask instead of doing modulo operations for stack wrapping.
- static const unsigned kDepthMask = kStackSize-1;
+ static const int kDepthMask = kStackSize-1;
STATIC_ASSERT(IS_POWER_OF_TWO(kStackSize));
- static inline unsigned OffsetForDepth(unsigned depth);
+ static inline int OffsetForDepth(int depth);
inline void PushLeft(ConsString* string);
inline void PushRight(ConsString* string);
inline void AdjustMaximumDepth();
inline void Pop();
- String* NextLeaf(bool* blew_stack, int32_t* type_out, unsigned* length_out);
- String* Search(unsigned* offset_out,
- int32_t* type_out,
- unsigned* length_out);
+ inline bool StackBlown() { return maximum_depth_ - depth_ == kStackSize; }
+ void Initialize(ConsString* cons_string, int offset);
+ String* Continue(int* offset_out);
+ String* NextLeaf(bool* blew_stack);
+ String* Search(int* offset_out);
- unsigned depth_;
- unsigned maximum_depth_;
// Stack must always contain only frames for which right traversal
// has not yet been performed.
ConsString* frames_[kStackSize];
- unsigned consumed_;
ConsString* root_;
+ int depth_;
+ int maximum_depth_;
+ int consumed_;
DISALLOW_COPY_AND_ASSIGN(ConsStringIteratorOp);
};
-// Note: this class is not GC-safe.
class StringCharacterStream {
public:
inline StringCharacterStream(String* string,
ConsStringIteratorOp* op,
- unsigned offset = 0);
+ int offset = 0);
inline uint16_t GetNext();
inline bool HasMore();
- inline void Reset(String* string, unsigned offset = 0);
- inline void VisitOneByteString(const uint8_t* chars, unsigned length);
- inline void VisitTwoByteString(const uint16_t* chars, unsigned length);
+ inline void Reset(String* string, int offset = 0);
+ inline void VisitOneByteString(const uint8_t* chars, int length);
+ inline void VisitTwoByteString(const uint16_t* chars, int length);
private:
bool is_one_byte_;
@@ -9487,10 +9638,11 @@ class Oddball: public HeapObject {
DECLARE_VERIFIER(Oddball)
// Initialize the fields.
- MUST_USE_RESULT MaybeObject* Initialize(Heap* heap,
- const char* to_string,
- Object* to_number,
- byte kind);
+ static void Initialize(Isolate* isolate,
+ Handle<Oddball> oddball,
+ const char* to_string,
+ Handle<Object> to_number,
+ byte kind);
// Layout description.
static const int kToStringOffset = HeapObject::kHeaderSize;
@@ -9507,6 +9659,7 @@ class Oddball: public HeapObject {
static const byte kUndefined = 5;
static const byte kUninitialized = 6;
static const byte kOther = 7;
+ static const byte kException = 8;
typedef FixedBodyDescriptor<kToStringOffset,
kToNumberOffset + kPointerSize,
@@ -9578,9 +9731,8 @@ class PropertyCell: public Cell {
static Handle<HeapType> UpdatedType(Handle<PropertyCell> cell,
Handle<Object> value);
- void AddDependentCompilationInfo(CompilationInfo* info);
-
- void AddDependentCode(Handle<Code> code);
+ static void AddDependentCompilationInfo(Handle<PropertyCell> cell,
+ CompilationInfo* info);
// Casting.
static inline PropertyCell* cast(Object* obj);
@@ -9623,18 +9775,21 @@ class JSProxy: public JSReceiver {
// Casting.
static inline JSProxy* cast(Object* obj);
- MUST_USE_RESULT MaybeObject* GetPropertyWithHandler(
- Object* receiver,
- Name* name);
- MUST_USE_RESULT MaybeObject* GetElementWithHandler(
- Object* receiver,
+ MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithHandler(
+ Handle<JSProxy> proxy,
+ Handle<Object> receiver,
+ Handle<Name> name);
+ MUST_USE_RESULT static inline MaybeHandle<Object> GetElementWithHandler(
+ Handle<JSProxy> proxy,
+ Handle<Object> receiver,
uint32_t index);
// If the handler defines an accessor property with a setter, invoke it.
// If it defines an accessor property without a setter, or a data property
// that is read-only, throw. In all these cases set '*done' to true,
// otherwise set it to false.
- static Handle<Object> SetPropertyViaPrototypesWithHandler(
+ MUST_USE_RESULT
+ static MaybeHandle<Object> SetPropertyViaPrototypesWithHandler(
Handle<JSProxy> proxy,
Handle<JSReceiver> receiver,
Handle<Name> name,
@@ -9660,10 +9815,12 @@ class JSProxy: public JSReceiver {
// Invoke a trap by name. If the trap does not exist on this's handler,
// but derived_trap is non-NULL, invoke that instead. May cause GC.
- Handle<Object> CallTrap(const char* name,
- Handle<Object> derived_trap,
- int argc,
- Handle<Object> args[]);
+ MUST_USE_RESULT static MaybeHandle<Object> CallTrap(
+ Handle<JSProxy> proxy,
+ const char* name,
+ Handle<Object> derived_trap,
+ int argc,
+ Handle<Object> args[]);
// Dispatched behavior.
DECLARE_PRINTER(JSProxy)
@@ -9688,27 +9845,32 @@ class JSProxy: public JSReceiver {
private:
friend class JSReceiver;
- static Handle<Object> SetPropertyWithHandler(Handle<JSProxy> proxy,
- Handle<JSReceiver> receiver,
- Handle<Name> name,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictMode strict_mode);
- static Handle<Object> SetElementWithHandler(Handle<JSProxy> proxy,
- Handle<JSReceiver> receiver,
- uint32_t index,
- Handle<Object> value,
- StrictMode strict_mode);
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithHandler(
+ Handle<JSProxy> proxy,
+ Handle<JSReceiver> receiver,
+ Handle<Name> name,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode);
+ MUST_USE_RESULT static inline MaybeHandle<Object> SetElementWithHandler(
+ Handle<JSProxy> proxy,
+ Handle<JSReceiver> receiver,
+ uint32_t index,
+ Handle<Object> value,
+ StrictMode strict_mode);
static bool HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name);
- static bool HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index);
+ static inline bool HasElementWithHandler(Handle<JSProxy> proxy,
+ uint32_t index);
- static Handle<Object> DeletePropertyWithHandler(Handle<JSProxy> proxy,
- Handle<Name> name,
- DeleteMode mode);
- static Handle<Object> DeleteElementWithHandler(Handle<JSProxy> proxy,
- uint32_t index,
- DeleteMode mode);
+ MUST_USE_RESULT static MaybeHandle<Object> DeletePropertyWithHandler(
+ Handle<JSProxy> proxy,
+ Handle<Name> name,
+ DeleteMode mode);
+ MUST_USE_RESULT static MaybeHandle<Object> DeleteElementWithHandler(
+ Handle<JSProxy> proxy,
+ uint32_t index,
+ DeleteMode mode);
MUST_USE_RESULT Object* GetIdentityHash();
@@ -9793,6 +9955,149 @@ class JSMap: public JSObject {
};
+// OrderedHashTableIterator is an iterator that iterates over the keys and
+// values of an OrderedHashTable.
+//
+// The hash table has a reference to the iterator and the iterators themselves
+// have references to the [next_iterator] and [previous_iterator], thus creating
+// a double linked list.
+//
+// When the hash table changes the iterators are called to update their [index]
+// and [count]. The hash table calls [EntryRemoved], [TableCompacted] as well
+// as [TableCleared].
+//
+// When an iterator is done it closes itself. It removes itself from the double
+// linked list and it sets its [table] to undefined, no longer keeping the
+// [table] alive.
+template<class Derived, class TableType>
+class OrderedHashTableIterator: public JSObject {
+ public:
+ // [table]: the backing hash table mapping keys to values.
+ DECL_ACCESSORS(table, Object)
+
+ // [index]: The index into the data table.
+ DECL_ACCESSORS(index, Smi)
+
+ // [count]: The logical index into the data table, ignoring the holes.
+ DECL_ACCESSORS(count, Smi)
+
+ // [kind]: The kind of iteration this is. One of the [Kind] enum values.
+ DECL_ACCESSORS(kind, Smi)
+
+ // [next_iterator]: Used as a double linked list for the live iterators.
+ DECL_ACCESSORS(next_iterator, Object)
+
+ // [previous_iterator]: Used as a double linked list for the live iterators.
+ DECL_ACCESSORS(previous_iterator, Object)
+
+#ifdef OBJECT_PRINT
+ void OrderedHashTableIteratorPrint(FILE* out);
+#endif
+
+ static const int kTableOffset = JSObject::kHeaderSize;
+ static const int kIndexOffset = kTableOffset + kPointerSize;
+ static const int kCountOffset = kIndexOffset + kPointerSize;
+ static const int kKindOffset = kCountOffset + kPointerSize;
+ static const int kNextIteratorOffset = kKindOffset + kPointerSize;
+ static const int kPreviousIteratorOffset = kNextIteratorOffset + kPointerSize;
+ static const int kSize = kPreviousIteratorOffset + kPointerSize;
+
+ enum Kind {
+ kKindKeys = 1,
+ kKindValues = 2,
+ kKindEntries = 3
+ };
+
+ // Called by the underlying [table] when an entry is removed.
+ void EntryRemoved(int index);
+
+ // Called by the underlying [table] when it is compacted/rehashed.
+ void TableCompacted() {
+ // All holes have been removed so index is now same as count.
+ set_index(count());
+ }
+
+ // Called by the underlying [table] when it is cleared.
+ void TableCleared() {
+ set_index(Smi::FromInt(0));
+ set_count(Smi::FromInt(0));
+ }
+
+ // Removes the iterator from the double linked list and removes its reference
+ // back to the [table].
+ void Close();
+
+ // Returns an iterator result object: {value: any, done: boolean} and moves
+ // the index to the next valid entry. Closes the iterator if moving past the
+ // end.
+ static Handle<JSObject> Next(Handle<Derived> iterator);
+
+ protected:
+ static Handle<Derived> CreateInternal(
+ Handle<Map> map, Handle<TableType> table, int kind);
+
+ private:
+ // Ensures [index] is not pointing to a hole.
+ void Seek();
+
+ // Moves [index] to next valid entry. Closes the iterator if moving past the
+ // end.
+ void MoveNext();
+
+ bool Closed() {
+ return table()->IsUndefined();
+ }
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(OrderedHashTableIterator);
+};
+
+
+class JSSetIterator: public OrderedHashTableIterator<JSSetIterator,
+ OrderedHashSet> {
+ public:
+ // Creates a new iterator associated with [table].
+ // [kind] needs to be one of the OrderedHashTableIterator Kind enum values.
+ static inline Handle<JSSetIterator> Create(
+ Handle<OrderedHashSet> table, int kind);
+
+ // Dispatched behavior.
+ DECLARE_PRINTER(JSSetIterator)
+ DECLARE_VERIFIER(JSSetIterator)
+
+ // Casting.
+ static inline JSSetIterator* cast(Object* obj);
+
+ static Handle<Object> ValueForKind(
+ Handle<JSSetIterator> iterator, int entry_index);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(JSSetIterator);
+};
+
+
+class JSMapIterator: public OrderedHashTableIterator<JSMapIterator,
+ OrderedHashMap> {
+ public:
+ // Creates a new iterator associated with [table].
+ // [kind] needs to be one of the OrderedHashTableIterator Kind enum values.
+ static inline Handle<JSMapIterator> Create(
+ Handle<OrderedHashMap> table, int kind);
+
+ // Dispatched behavior.
+ DECLARE_PRINTER(JSMapIterator)
+ DECLARE_VERIFIER(JSMapIterator)
+
+ // Casting.
+ static inline JSMapIterator* cast(Object* obj);
+
+ static Handle<Object> ValueForKind(
+ Handle<JSMapIterator> iterator, int entry_index);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(JSMapIterator);
+};
+
+
// Base class for both JSWeakMap and JSWeakSet
class JSWeakCollection: public JSObject {
public:
@@ -10034,9 +10339,6 @@ class JSArray: public JSObject {
uint32_t index,
Handle<Object> value);
- MUST_USE_RESULT MaybeObject* JSArrayUpdateLengthFromIndex(uint32_t index,
- Object* value);
-
// Initialize the array with the given capacity. The function may
// fail due to out-of-memory situations, but only if the requested
// capacity is non-zero.
@@ -10045,8 +10347,9 @@ class JSArray: public JSObject {
// Initializes the array to a certain length.
inline bool AllowsSetElementsLength();
// Can cause GC.
- static Handle<Object> SetElementsLength(Handle<JSArray> array,
- Handle<Object> length);
+ MUST_USE_RESULT static MaybeHandle<Object> SetElementsLength(
+ Handle<JSArray> array,
+ Handle<Object> length);
// Set the content of the array to the content of storage.
static inline void SetContent(Handle<JSArray> array,
@@ -10582,7 +10885,6 @@ class TypeSwitchInfo: public Struct {
};
-#ifdef ENABLE_DEBUGGER_SUPPORT
// The DebugInfo class holds additional information for a function being
// debugged.
class DebugInfo: public Struct {
@@ -10686,7 +10988,6 @@ class BreakPointInfo: public Struct {
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
};
-#endif // ENABLE_DEBUGGER_SUPPORT
#undef DECL_BOOLEAN_ACCESSORS
diff --git a/deps/v8/src/once.cc b/deps/v8/src/once.cc
index 37fe369fb6..412c66a1db 100644
--- a/deps/v8/src/once.cc
+++ b/deps/v8/src/once.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "once.h"
diff --git a/deps/v8/src/once.h b/deps/v8/src/once.h
index a44b8fafbf..938af281ca 100644
--- a/deps/v8/src/once.h
+++ b/deps/v8/src/once.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// emulates google3/base/once.h
//
diff --git a/deps/v8/src/optimizing-compiler-thread.cc b/deps/v8/src/optimizing-compiler-thread.cc
index fb3eac5d50..f26eb88acb 100644
--- a/deps/v8/src/optimizing-compiler-thread.cc
+++ b/deps/v8/src/optimizing-compiler-thread.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "optimizing-compiler-thread.h"
diff --git a/deps/v8/src/optimizing-compiler-thread.h b/deps/v8/src/optimizing-compiler-thread.h
index eae1f608f9..7e27527009 100644
--- a/deps/v8/src/optimizing-compiler-thread.h
+++ b/deps/v8/src/optimizing-compiler-thread.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_OPTIMIZING_COMPILER_THREAD_H_
#define V8_OPTIMIZING_COMPILER_THREAD_H_
diff --git a/deps/v8/src/parser.cc b/deps/v8/src/parser.cc
index a00adb8c1e..f07f37ebb2 100644
--- a/deps/v8/src/parser.cc
+++ b/deps/v8/src/parser.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -205,26 +182,31 @@ void RegExpBuilder::AddQuantifierToAtom(
}
-Handle<String> Parser::LookupCachedSymbol(int symbol_id) {
- // Make sure the cache is large enough to hold the symbol identifier.
- if (symbol_cache_.length() <= symbol_id) {
- // Increase length to index + 1.
- symbol_cache_.AddBlock(Handle<String>::null(),
- symbol_id + 1 - symbol_cache_.length(), zone());
+ScriptData* ScriptData::New(const char* data, int length) {
+ // The length is obviously invalid.
+ if (length % sizeof(unsigned) != 0) {
+ return NULL;
}
- Handle<String> result = symbol_cache_.at(symbol_id);
- if (result.is_null()) {
- result = scanner()->AllocateInternalizedString(isolate_);
- ASSERT(!result.is_null());
- symbol_cache_.at(symbol_id) = result;
- return result;
+
+ int deserialized_data_length = length / sizeof(unsigned);
+ unsigned* deserialized_data;
+ bool owns_store = reinterpret_cast<intptr_t>(data) % sizeof(unsigned) != 0;
+ if (owns_store) {
+ // Copy the data to align it.
+ deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
+ i::CopyBytes(reinterpret_cast<char*>(deserialized_data),
+ data, static_cast<size_t>(length));
+ } else {
+ // If aligned, don't create a copy of the data.
+ deserialized_data = reinterpret_cast<unsigned*>(const_cast<char*>(data));
}
- isolate()->counters()->total_preparse_symbols_skipped()->Increment();
- return result;
+ return new ScriptData(
+ Vector<unsigned>(deserialized_data, deserialized_data_length),
+ owns_store);
}
-FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
+FunctionEntry ScriptData::GetFunctionEntry(int start) {
// The current pre-data entry must be a FunctionEntry with the given
// start position.
if ((function_index_ + FunctionEntry::kSize <= store_.length())
@@ -238,12 +220,12 @@ FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
}
-int ScriptDataImpl::GetSymbolIdentifier() {
+int ScriptData::GetSymbolIdentifier() {
return ReadNumber(&symbol_data_);
}
-bool ScriptDataImpl::SanityCheck() {
+bool ScriptData::SanityCheck() {
// Check that the header data is valid and doesn't specify
// point to positions outside the store.
if (store_.length() < PreparseDataConstants::kHeaderSize) return false;
@@ -279,10 +261,6 @@ bool ScriptDataImpl::SanityCheck() {
static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]);
if (functions_size < 0) return false;
if (functions_size % FunctionEntry::kSize != 0) return false;
- // Check that the count of symbols is non-negative.
- int symbol_count =
- static_cast<int>(store_[PreparseDataConstants::kSymbolCountOffset]);
- if (symbol_count < 0) return false;
// Check that the total size has room for header and function entries.
int minimum_size =
PreparseDataConstants::kHeaderSize + functions_size;
@@ -292,7 +270,7 @@ bool ScriptDataImpl::SanityCheck() {
-const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
+const char* ScriptData::ReadString(unsigned* start, int* chars) {
int length = start[0];
char* result = NewArray<char>(length + 1);
for (int i = 0; i < length; i++) {
@@ -304,20 +282,25 @@ const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
}
-Scanner::Location ScriptDataImpl::MessageLocation() {
+Scanner::Location ScriptData::MessageLocation() const {
int beg_pos = Read(PreparseDataConstants::kMessageStartPos);
int end_pos = Read(PreparseDataConstants::kMessageEndPos);
return Scanner::Location(beg_pos, end_pos);
}
-const char* ScriptDataImpl::BuildMessage() {
+bool ScriptData::IsReferenceError() const {
+ return Read(PreparseDataConstants::kIsReferenceErrorPos);
+}
+
+
+const char* ScriptData::BuildMessage() const {
unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
return ReadString(start, NULL);
}
-Vector<const char*> ScriptDataImpl::BuildArgs() {
+Vector<const char*> ScriptData::BuildArgs() const {
int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
const char** array = NewArray<const char*>(arg_count);
// Position after text found by skipping past length field and
@@ -333,12 +316,12 @@ Vector<const char*> ScriptDataImpl::BuildArgs() {
}
-unsigned ScriptDataImpl::Read(int position) {
+unsigned ScriptData::Read(int position) const {
return store_[PreparseDataConstants::kHeaderSize + position];
}
-unsigned* ScriptDataImpl::ReadAddress(int position) {
+unsigned* ScriptData::ReadAddress(int position) const {
return &store_[PreparseDataConstants::kHeaderSize + position];
}
@@ -418,10 +401,9 @@ class TargetScope BASE_EMBEDDED {
// Implementation of Parser
bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const {
- return identifier.is_identical_to(
- parser_->isolate()->factory()->eval_string()) ||
- identifier.is_identical_to(
- parser_->isolate()->factory()->arguments_string());
+ Factory* factory = parser_->isolate()->factory();
+ return identifier.is_identical_to(factory->eval_string())
+ || identifier.is_identical_to(factory->arguments_string());
}
@@ -480,19 +462,6 @@ Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) {
}
-void ParserTraits::CheckStrictModeLValue(Expression* expression,
- bool* ok) {
- VariableProxy* lhs = expression != NULL
- ? expression->AsVariableProxy()
- : NULL;
- if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
- parser_->ReportMessage("strict_eval_arguments",
- Vector<const char*>::empty());
- *ok = false;
- }
-}
-
-
bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
Expression** x, Expression* y, Token::Value op, int pos,
AstNodeFactory<AstConstructionVisitor>* factory) {
@@ -599,6 +568,59 @@ Expression* ParserTraits::BuildUnaryExpression(
}
+Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) {
+ return NewThrowError(
+ parser_->isolate()->factory()->MakeReferenceError_string(),
+ message, HandleVector<Object>(NULL, 0), pos);
+}
+
+
+Expression* ParserTraits::NewThrowSyntaxError(
+ const char* message, Handle<Object> arg, int pos) {
+ int argc = arg.is_null() ? 0 : 1;
+ Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc);
+ return NewThrowError(
+ parser_->isolate()->factory()->MakeSyntaxError_string(),
+ message, arguments, pos);
+}
+
+
+Expression* ParserTraits::NewThrowTypeError(
+ const char* message, Handle<Object> arg, int pos) {
+ int argc = arg.is_null() ? 0 : 1;
+ Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc);
+ return NewThrowError(
+ parser_->isolate()->factory()->MakeTypeError_string(),
+ message, arguments, pos);
+}
+
+
+Expression* ParserTraits::NewThrowError(
+ Handle<String> constructor, const char* message,
+ Vector<Handle<Object> > arguments, int pos) {
+ Zone* zone = parser_->zone();
+ Factory* factory = parser_->isolate()->factory();
+ int argc = arguments.length();
+ Handle<FixedArray> elements = factory->NewFixedArray(argc, TENURED);
+ for (int i = 0; i < argc; i++) {
+ Handle<Object> element = arguments[i];
+ if (!element.is_null()) {
+ elements->set(i, *element);
+ }
+ }
+ Handle<JSArray> array =
+ factory->NewJSArrayWithElements(elements, FAST_ELEMENTS, TENURED);
+
+ ZoneList<Expression*>* args = new(zone) ZoneList<Expression*>(2, zone);
+ Handle<String> type = factory->InternalizeUtf8String(message);
+ args->Add(parser_->factory()->NewLiteral(type, pos), zone);
+ args->Add(parser_->factory()->NewLiteral(array, pos), zone);
+ CallRuntime* call_constructor =
+ parser_->factory()->NewCallRuntime(constructor, NULL, args, pos);
+ return parser_->factory()->NewThrow(call_constructor, pos);
+}
+
+
void ParserTraits::ReportMessageAt(Scanner::Location source_location,
const char* message,
Vector<const char*> args,
@@ -615,8 +637,8 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location,
Factory* factory = parser_->isolate()->factory();
Handle<FixedArray> elements = factory->NewFixedArray(args.length());
for (int i = 0; i < args.length(); i++) {
- Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i]));
- ASSERT(!arg_string.is_null());
+ Handle<String> arg_string =
+ factory->NewStringFromUtf8(CStrVector(args[i])).ToHandleChecked();
elements->set(i, *arg_string);
}
Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
@@ -662,20 +684,8 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location,
Handle<String> ParserTraits::GetSymbol(Scanner* scanner) {
- if (parser_->cached_data_mode() == CONSUME_CACHED_DATA) {
- int symbol_id = (*parser_->cached_data())->GetSymbolIdentifier();
- // If there is no symbol data, -1 will be returned.
- if (symbol_id >= 0 &&
- symbol_id < (*parser_->cached_data())->symbol_count()) {
- return parser_->LookupCachedSymbol(symbol_id);
- }
- } else if (parser_->cached_data_mode() == PRODUCE_CACHED_DATA) {
- if (parser_->log_->ShouldLogSymbols()) {
- parser_->scanner()->LogSymbol(parser_->log_, parser_->position());
- }
- }
Handle<String> result =
- parser_->scanner()->AllocateInternalizedString(parser_->isolate_);
+ parser_->scanner()->AllocateInternalizedString(parser_->isolate());
ASSERT(!result.is_null());
return result;
}
@@ -774,7 +784,6 @@ Parser::Parser(CompilationInfo* info)
info->zone(),
this),
isolate_(info->isolate()),
- symbol_cache_(0, info->zone()),
script_(info->script()),
scanner_(isolate_->unicode_cache()),
reusable_preparser_(NULL),
@@ -815,7 +824,7 @@ FunctionLiteral* Parser::ParseProgram() {
(*cached_data_)->Initialize();
}
- source->TryFlatten();
+ source = String::Flatten(source);
FunctionLiteral* result;
if (source->IsExternalTwoByteString()) {
// Notice that the stream is destroyed at the end of the branch block.
@@ -845,8 +854,10 @@ FunctionLiteral* Parser::ParseProgram() {
PrintF(" - took %0.3f ms]\n", ms);
}
if (cached_data_mode_ == PRODUCE_CACHED_DATA) {
- Vector<unsigned> store = recorder.ExtractData();
- *cached_data_ = new ScriptDataImpl(store);
+ if (result != NULL) {
+ Vector<unsigned> store = recorder.ExtractData();
+ *cached_data_ = new ScriptData(store);
+ }
log_ = NULL;
}
return result;
@@ -928,7 +939,6 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
FunctionLiteral::kNotGenerator,
0);
result->set_ast_properties(factory()->visitor()->ast_properties());
- result->set_slot_processor(factory()->visitor()->slot_processor());
result->set_dont_optimize_reason(
factory()->visitor()->dont_optimize_reason());
} else if (stack_overflow()) {
@@ -954,7 +964,7 @@ FunctionLiteral* Parser::ParseLazy() {
Handle<SharedFunctionInfo> shared_info = info()->shared_info();
// Initialize parser state.
- source->TryFlatten();
+ source = String::Flatten(source);
FunctionLiteral* result;
if (source->IsExternalTwoByteString()) {
ExternalTwoByteStringUtf16CharacterStream stream(
@@ -1082,7 +1092,8 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
// Check "use strict" directive (ES5 14.1).
if (strict_mode() == SLOPPY &&
- directive->Equals(isolate()->heap()->use_strict_string()) &&
+ String::Equals(isolate()->factory()->use_strict_string(),
+ directive) &&
token_loc.end_pos - token_loc.beg_pos ==
isolate()->heap()->use_strict_string()->length() + 2) {
// TODO(mstarzinger): Global strict eval calls, need their own scope
@@ -1151,8 +1162,8 @@ Statement* Parser::ParseModuleElement(ZoneStringList* labels,
ExpressionStatement* estmt = stmt->AsExpressionStatement();
if (estmt != NULL &&
estmt->expression()->AsVariableProxy() != NULL &&
- estmt->expression()->AsVariableProxy()->name()->Equals(
- isolate()->heap()->module_string()) &&
+ String::Equals(isolate()->factory()->module_string(),
+ estmt->expression()->AsVariableProxy()->name()) &&
!scanner()->literal_contains_escapes()) {
return ParseModuleDeclaration(NULL, ok);
}
@@ -1707,18 +1718,14 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
// In harmony we treat re-declarations as early errors. See
// ES5 16 for a definition of early errors.
SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
- const char* elms[2] = { "Variable", c_string.get() };
- Vector<const char*> args(elms, 2);
- ReportMessage("redeclaration", args);
+ const char* elms[1] = { c_string.get() };
+ Vector<const char*> args(elms, 1);
+ ReportMessage("var_redeclaration", args);
*ok = false;
return;
}
- Handle<String> message_string =
- isolate()->factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("Variable"));
- Expression* expression =
- NewThrowTypeError(isolate()->factory()->redeclaration_string(),
- message_string, name);
+ Expression* expression = NewThrowTypeError(
+ "var_redeclaration", name, declaration->position());
declaration_scope->SetIllegalRedeclaration(expression);
}
}
@@ -2327,9 +2334,9 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
// make later anyway so we should go back and fix this then.
if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
SmartArrayPointer<char> c_string = label->ToCString(DISALLOW_NULLS);
- const char* elms[2] = { "Label", c_string.get() };
- Vector<const char*> args(elms, 2);
- ReportMessage("redeclaration", args);
+ const char* elms[1] = { c_string.get() };
+ Vector<const char*> args(elms, 1);
+ ReportMessage("label_redeclaration", args);
*ok = false;
return NULL;
}
@@ -2353,8 +2360,8 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
!scanner()->HasAnyLineTerminatorBeforeNext() &&
expr != NULL &&
expr->AsVariableProxy() != NULL &&
- expr->AsVariableProxy()->name()->Equals(
- isolate()->heap()->native_string()) &&
+ String::Equals(isolate()->factory()->native_string(),
+ expr->AsVariableProxy()->name()) &&
!scanner()->literal_contains_escapes()) {
return ParseNativeDeclaration(ok);
}
@@ -2365,8 +2372,8 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
peek() != Token::IDENTIFIER ||
scanner()->HasAnyLineTerminatorBeforeNext() ||
expr->AsVariableProxy() == NULL ||
- !expr->AsVariableProxy()->name()->Equals(
- isolate()->heap()->module_string()) ||
+ !String::Equals(isolate()->factory()->module_string(),
+ expr->AsVariableProxy()->name()) ||
scanner()->literal_contains_escapes()) {
ExpectSemicolon(CHECK_OK);
}
@@ -2474,7 +2481,7 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
// reporting any errors on it, because of the way errors are
// reported (underlining).
Expect(Token::RETURN, CHECK_OK);
- int pos = position();
+ Scanner::Location loc = scanner()->location();
Token::Value tok = peek();
Statement* result;
@@ -2492,24 +2499,17 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
Expression* generator = factory()->NewVariableProxy(
function_state_->generator_object_variable());
Expression* yield = factory()->NewYield(
- generator, return_value, Yield::FINAL, pos);
- result = factory()->NewExpressionStatement(yield, pos);
+ generator, return_value, Yield::FINAL, loc.beg_pos);
+ result = factory()->NewExpressionStatement(yield, loc.beg_pos);
} else {
- result = factory()->NewReturnStatement(return_value, pos);
+ result = factory()->NewReturnStatement(return_value, loc.beg_pos);
}
- // An ECMAScript program is considered syntactically incorrect if it
- // contains a return statement that is not within the body of a
- // function. See ECMA-262, section 12.9, page 67.
- //
- // To be consistent with KJS we report the syntax error at runtime.
- Scope* declaration_scope = scope_->DeclarationScope();
- if (declaration_scope->is_global_scope() ||
- declaration_scope->is_eval_scope()) {
- Handle<String> message = isolate()->factory()->illegal_return_string();
- Expression* throw_error =
- NewThrowSyntaxError(message, Handle<Object>::null());
- return factory()->NewExpressionStatement(throw_error, pos);
+ Scope* decl_scope = scope_->DeclarationScope();
+ if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) {
+ ReportMessageAt(loc, "illegal_return");
+ *ok = false;
+ return NULL;
}
return result;
}
@@ -2941,9 +2941,11 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
// TODO(keuchel): Move the temporary variable to the block scope, after
// implementing stack allocated block scoped variables.
Factory* heap_factory = isolate()->factory();
- Handle<String> tempstr =
- heap_factory->NewConsString(heap_factory->dot_for_string(), name);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate(), tempstr, 0);
+ Handle<String> tempstr;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate(), tempstr,
+ heap_factory->NewConsString(heap_factory->dot_for_string(), name),
+ 0);
Handle<String> tempname = heap_factory->InternalizeString(tempstr);
Variable* temp = scope_->DeclarationScope()->NewTemporary(tempname);
VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
@@ -2987,11 +2989,9 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
bool accept_OF = expression->AsVariableProxy();
if (CheckInOrOf(accept_OF, &mode)) {
- if (expression == NULL || !expression->IsValidLeftHandSide()) {
- ReportMessageAt(lhs_location, "invalid_lhs_in_for", true);
- *ok = false;
- return NULL;
- }
+ expression = this->CheckAndRewriteReferenceExpression(
+ expression, lhs_location, "invalid_lhs_in_for", CHECK_OK);
+
ForEachStatement* loop =
factory()->NewForEachStatement(mode, labels, pos);
Target target(&this->target_stack_, loop);
@@ -3078,10 +3078,10 @@ DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
}
-void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) {
+void Parser::ReportInvalidCachedData(Handle<String> name, bool* ok) {
SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS);
const char* element[1] = { name_string.get() };
- ReportMessage("invalid_preparser_data",
+ ReportMessage("invalid_cached_data_function",
Vector<const char*>(element, 1));
*ok = false;
}
@@ -3200,10 +3200,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
? FunctionLiteral::kIsParenthesized
: FunctionLiteral::kNotParenthesized;
- FunctionLiteral::IsGeneratorFlag generator = is_generator
- ? FunctionLiteral::kIsGenerator
- : FunctionLiteral::kNotGenerator;
- DeferredFeedbackSlotProcessor* slot_processor;
AstProperties ast_properties;
BailoutReason dont_optimize_reason = kNoReason;
// Parse function body.
@@ -3331,140 +3327,14 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
parenthesized_function_ = false; // The bit was set for this function only.
if (is_lazily_parsed) {
- int function_block_pos = position();
- FunctionEntry entry;
- if (cached_data_mode_ == CONSUME_CACHED_DATA) {
- // If we have cached data, we use it to skip parsing the function body.
- // The data contains the information we need to construct the lazy
- // function.
- entry = (*cached_data())->GetFunctionEntry(function_block_pos);
- if (entry.is_valid()) {
- if (entry.end_pos() <= function_block_pos) {
- // End position greater than end of stream is safe, and hard
- // to check.
- ReportInvalidPreparseData(function_name, CHECK_OK);
- }
- scanner()->SeekForward(entry.end_pos() - 1);
-
- scope->set_end_position(entry.end_pos());
- Expect(Token::RBRACE, CHECK_OK);
- isolate()->counters()->total_preparse_skipped()->Increment(
- scope->end_position() - function_block_pos);
- materialized_literal_count = entry.literal_count();
- expected_property_count = entry.property_count();
- scope_->SetStrictMode(entry.strict_mode());
- } else {
- // This case happens when we have preparse data but it doesn't contain
- // an entry for the function. As a safety net, fall back to eager
- // parsing. It is unclear whether PreParser's laziness analysis can
- // produce different results than the Parser's laziness analysis (see
- // https://codereview.chromium.org/7565003 ). In this case, we must
- // discard all the preparse data, since the symbol data will be wrong.
- is_lazily_parsed = false;
- cached_data_mode_ = NO_CACHED_DATA;
- }
- } else {
- // With no cached data, we partially parse the function, without
- // building an AST. This gathers the data needed to build a lazy
- // function.
- // FIXME(marja): Now the PreParser doesn't need to log functions /
- // symbols; only errors -> clean that up.
- SingletonLogger logger;
- PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger);
- if (result == PreParser::kPreParseStackOverflow) {
- // Propagate stack overflow.
- set_stack_overflow();
- *ok = false;
- return NULL;
- }
- if (logger.has_error()) {
- const char* arg = logger.argument_opt();
- Vector<const char*> args;
- if (arg != NULL) {
- args = Vector<const char*>(&arg, 1);
- }
- ParserTraits::ReportMessageAt(
- Scanner::Location(logger.start(), logger.end()),
- logger.message(),
- args);
- *ok = false;
- return NULL;
- }
- scope->set_end_position(logger.end());
- Expect(Token::RBRACE, CHECK_OK);
- isolate()->counters()->total_preparse_skipped()->Increment(
- scope->end_position() - function_block_pos);
- materialized_literal_count = logger.literals();
- expected_property_count = logger.properties();
- scope_->SetStrictMode(logger.strict_mode());
- if (cached_data_mode_ == PRODUCE_CACHED_DATA) {
- ASSERT(log_);
- // Position right after terminal '}'.
- int body_end = scanner()->location().end_pos;
- log_->LogFunction(function_block_pos, body_end,
- materialized_literal_count,
- expected_property_count,
- scope_->strict_mode());
- }
- }
- }
-
- if (!is_lazily_parsed) {
- // Everything inside an eagerly parsed function will be parsed eagerly
- // (see comment above).
- ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
- body = new(zone()) ZoneList<Statement*>(8, zone());
- if (fvar != NULL) {
- VariableProxy* fproxy = scope_->NewUnresolved(
- factory(), function_name, Interface::NewConst());
- fproxy->BindTo(fvar);
- body->Add(factory()->NewExpressionStatement(
- factory()->NewAssignment(fvar_init_op,
- fproxy,
- factory()->NewThisFunction(pos),
- RelocInfo::kNoPosition),
- RelocInfo::kNoPosition), zone());
- }
-
- // For generators, allocate and yield an iterator on function entry.
- if (is_generator) {
- ZoneList<Expression*>* arguments =
- new(zone()) ZoneList<Expression*>(0, zone());
- CallRuntime* allocation = factory()->NewCallRuntime(
- isolate()->factory()->empty_string(),
- Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject),
- arguments, pos);
- VariableProxy* init_proxy = factory()->NewVariableProxy(
- function_state_->generator_object_variable());
- Assignment* assignment = factory()->NewAssignment(
- Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
- VariableProxy* get_proxy = factory()->NewVariableProxy(
- function_state_->generator_object_variable());
- Yield* yield = factory()->NewYield(
- get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition);
- body->Add(factory()->NewExpressionStatement(
- yield, RelocInfo::kNoPosition), zone());
- }
-
- ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK);
-
- if (is_generator) {
- VariableProxy* get_proxy = factory()->NewVariableProxy(
- function_state_->generator_object_variable());
- Expression *undefined = factory()->NewLiteral(
- isolate()->factory()->undefined_value(), RelocInfo::kNoPosition);
- Yield* yield = factory()->NewYield(
- get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition);
- body->Add(factory()->NewExpressionStatement(
- yield, RelocInfo::kNoPosition), zone());
- }
-
+ SkipLazyFunctionBody(function_name, &materialized_literal_count,
+ &expected_property_count, CHECK_OK);
+ } else {
+ body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
+ is_generator, CHECK_OK);
materialized_literal_count = function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count();
handler_count = function_state.handler_count();
-
- Expect(Token::RBRACE, CHECK_OK);
- scope->set_end_position(scanner()->location().end_pos);
}
// Validate strict mode. We can do this only after parsing the function,
@@ -3500,7 +3370,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
CHECK_OK);
}
ast_properties = *factory()->visitor()->ast_properties();
- slot_processor = factory()->visitor()->slot_processor();
dont_optimize_reason = factory()->visitor()->dont_optimize_reason();
}
@@ -3508,6 +3377,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
CheckConflictingVarDeclarations(scope, CHECK_OK);
}
+ FunctionLiteral::IsGeneratorFlag generator = is_generator
+ ? FunctionLiteral::kIsGenerator
+ : FunctionLiteral::kNotGenerator;
FunctionLiteral* function_literal =
factory()->NewFunctionLiteral(function_name,
scope,
@@ -3524,7 +3396,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
pos);
function_literal->set_function_token_position(function_token_pos);
function_literal->set_ast_properties(&ast_properties);
- function_literal->set_slot_processor(slot_processor);
function_literal->set_dont_optimize_reason(dont_optimize_reason);
if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
@@ -3532,7 +3403,149 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
}
-PreParser::PreParseResult Parser::LazyParseFunctionLiteral(
+void Parser::SkipLazyFunctionBody(Handle<String> function_name,
+ int* materialized_literal_count,
+ int* expected_property_count,
+ bool* ok) {
+ int function_block_pos = position();
+ if (cached_data_mode_ == CONSUME_CACHED_DATA) {
+ // If we have cached data, we use it to skip parsing the function body. The
+ // data contains the information we need to construct the lazy function.
+ FunctionEntry entry =
+ (*cached_data())->GetFunctionEntry(function_block_pos);
+ if (entry.is_valid()) {
+ if (entry.end_pos() <= function_block_pos) {
+ // End position greater than end of stream is safe, and hard to check.
+ ReportInvalidCachedData(function_name, ok);
+ if (!*ok) {
+ return;
+ }
+ }
+ scanner()->SeekForward(entry.end_pos() - 1);
+
+ scope_->set_end_position(entry.end_pos());
+ Expect(Token::RBRACE, ok);
+ if (!*ok) {
+ return;
+ }
+ isolate()->counters()->total_preparse_skipped()->Increment(
+ scope_->end_position() - function_block_pos);
+ *materialized_literal_count = entry.literal_count();
+ *expected_property_count = entry.property_count();
+ scope_->SetStrictMode(entry.strict_mode());
+ } else {
+ // This case happens when we have preparse data but it doesn't contain an
+ // entry for the function. Fail the compilation.
+ ReportInvalidCachedData(function_name, ok);
+ return;
+ }
+ } else {
+ // With no cached data, we partially parse the function, without building an
+ // AST. This gathers the data needed to build a lazy function.
+ SingletonLogger logger;
+ PreParser::PreParseResult result =
+ ParseLazyFunctionBodyWithPreParser(&logger);
+ if (result == PreParser::kPreParseStackOverflow) {
+ // Propagate stack overflow.
+ set_stack_overflow();
+ *ok = false;
+ return;
+ }
+ if (logger.has_error()) {
+ const char* arg = logger.argument_opt();
+ Vector<const char*> args;
+ if (arg != NULL) {
+ args = Vector<const char*>(&arg, 1);
+ }
+ ParserTraits::ReportMessageAt(
+ Scanner::Location(logger.start(), logger.end()),
+ logger.message(), args, logger.is_reference_error());
+ *ok = false;
+ return;
+ }
+ scope_->set_end_position(logger.end());
+ Expect(Token::RBRACE, ok);
+ if (!*ok) {
+ return;
+ }
+ isolate()->counters()->total_preparse_skipped()->Increment(
+ scope_->end_position() - function_block_pos);
+ *materialized_literal_count = logger.literals();
+ *expected_property_count = logger.properties();
+ scope_->SetStrictMode(logger.strict_mode());
+ if (cached_data_mode_ == PRODUCE_CACHED_DATA) {
+ ASSERT(log_);
+ // Position right after terminal '}'.
+ int body_end = scanner()->location().end_pos;
+ log_->LogFunction(function_block_pos, body_end,
+ *materialized_literal_count,
+ *expected_property_count,
+ scope_->strict_mode());
+ }
+ }
+}
+
+
+ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
+ Handle<String> function_name, int pos, Variable* fvar,
+ Token::Value fvar_init_op, bool is_generator, bool* ok) {
+ // Everything inside an eagerly parsed function will be parsed eagerly
+ // (see comment above).
+ ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
+ ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone());
+ if (fvar != NULL) {
+ VariableProxy* fproxy = scope_->NewUnresolved(
+ factory(), function_name, Interface::NewConst());
+ fproxy->BindTo(fvar);
+ body->Add(factory()->NewExpressionStatement(
+ factory()->NewAssignment(fvar_init_op,
+ fproxy,
+ factory()->NewThisFunction(pos),
+ RelocInfo::kNoPosition),
+ RelocInfo::kNoPosition), zone());
+ }
+
+ // For generators, allocate and yield an iterator on function entry.
+ if (is_generator) {
+ ZoneList<Expression*>* arguments =
+ new(zone()) ZoneList<Expression*>(0, zone());
+ CallRuntime* allocation = factory()->NewCallRuntime(
+ isolate()->factory()->empty_string(),
+ Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject),
+ arguments, pos);
+ VariableProxy* init_proxy = factory()->NewVariableProxy(
+ function_state_->generator_object_variable());
+ Assignment* assignment = factory()->NewAssignment(
+ Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
+ VariableProxy* get_proxy = factory()->NewVariableProxy(
+ function_state_->generator_object_variable());
+ Yield* yield = factory()->NewYield(
+ get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition);
+ body->Add(factory()->NewExpressionStatement(
+ yield, RelocInfo::kNoPosition), zone());
+ }
+
+ ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK);
+
+ if (is_generator) {
+ VariableProxy* get_proxy = factory()->NewVariableProxy(
+ function_state_->generator_object_variable());
+ Expression *undefined = factory()->NewLiteral(
+ isolate()->factory()->undefined_value(), RelocInfo::kNoPosition);
+ Yield* yield = factory()->NewYield(
+ get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition);
+ body->Add(factory()->NewExpressionStatement(
+ yield, RelocInfo::kNoPosition), zone());
+ }
+
+ Expect(Token::RBRACE, CHECK_OK);
+ scope_->set_end_position(scanner()->location().end_pos);
+
+ return body;
+}
+
+
+PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
SingletonLogger* logger) {
HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse());
ASSERT_EQ(Token::LBRACE, scanner()->current_token());
@@ -3626,13 +3639,13 @@ void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
// errors. See ES5 16 for a definition of early errors.
Handle<String> name = decl->proxy()->name();
SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
- const char* elms[2] = { "Variable", c_string.get() };
- Vector<const char*> args(elms, 2);
+ const char* elms[1] = { c_string.get() };
+ Vector<const char*> args(elms, 1);
int position = decl->proxy()->position();
Scanner::Location location = position == RelocInfo::kNoPosition
? Scanner::Location::invalid()
: Scanner::Location(position, position + 1);
- ParserTraits::ReportMessageAt(location, "redeclaration", args);
+ ParserTraits::ReportMessageAt(location, "var_redeclaration", args);
*ok = false;
}
}
@@ -3695,58 +3708,6 @@ void Parser::RegisterTargetUse(Label* target, Target* stop) {
}
-Expression* Parser::NewThrowReferenceError(Handle<String> message) {
- return NewThrowError(isolate()->factory()->MakeReferenceError_string(),
- message, HandleVector<Object>(NULL, 0));
-}
-
-
-Expression* Parser::NewThrowSyntaxError(Handle<String> message,
- Handle<Object> first) {
- int argc = first.is_null() ? 0 : 1;
- Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc);
- return NewThrowError(
- isolate()->factory()->MakeSyntaxError_string(), message, arguments);
-}
-
-
-Expression* Parser::NewThrowTypeError(Handle<String> message,
- Handle<Object> first,
- Handle<Object> second) {
- ASSERT(!first.is_null() && !second.is_null());
- Handle<Object> elements[] = { first, second };
- Vector< Handle<Object> > arguments =
- HandleVector<Object>(elements, ARRAY_SIZE(elements));
- return NewThrowError(
- isolate()->factory()->MakeTypeError_string(), message, arguments);
-}
-
-
-Expression* Parser::NewThrowError(Handle<String> constructor,
- Handle<String> message,
- Vector< Handle<Object> > arguments) {
- int argc = arguments.length();
- Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc,
- TENURED);
- for (int i = 0; i < argc; i++) {
- Handle<Object> element = arguments[i];
- if (!element.is_null()) {
- elements->set(i, *element);
- }
- }
- Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(
- elements, FAST_ELEMENTS, TENURED);
-
- int pos = position();
- ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2, zone());
- args->Add(factory()->NewLiteral(message, pos), zone());
- args->Add(factory()->NewLiteral(array, pos), zone());
- CallRuntime* call_constructor =
- factory()->NewCallRuntime(constructor, NULL, args, pos);
- return factory()->NewThrow(call_constructor, pos);
-}
-
-
// ----------------------------------------------------------------------------
// Regular expressions
@@ -3820,8 +3781,7 @@ bool RegExpParser::simple() {
RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
failed_ = true;
- *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED);
- ASSERT(!error_->is_null());
+ *error_ = isolate()->factory()->NewStringFromAscii(message).ToHandleChecked();
// Zip to the end to make sure the no more input is read.
current_ = kEndMarker;
next_pos_ = in()->length();
@@ -4556,27 +4516,27 @@ RegExpTree* RegExpParser::ParseCharacterClass() {
// ----------------------------------------------------------------------------
// The Parser interface.
-ScriptDataImpl::~ScriptDataImpl() {
+ScriptData::~ScriptData() {
if (owns_store_) store_.Dispose();
}
-int ScriptDataImpl::Length() {
+int ScriptData::Length() {
return store_.length() * sizeof(unsigned);
}
-const char* ScriptDataImpl::Data() {
+const char* ScriptData::Data() {
return reinterpret_cast<const char*>(store_.start());
}
-bool ScriptDataImpl::HasError() {
+bool ScriptData::HasError() {
return has_error();
}
-void ScriptDataImpl::Initialize() {
+void ScriptData::Initialize() {
// Prepares state for use.
if (store_.length() >= PreparseDataConstants::kHeaderSize) {
function_index_ = PreparseDataConstants::kHeaderSize;
@@ -4593,7 +4553,7 @@ void ScriptDataImpl::Initialize() {
}
-int ScriptDataImpl::ReadNumber(byte** source) {
+int ScriptData::ReadNumber(byte** source) {
// Reads a number from symbol_data_ in base 128. The most significant
// bit marks that there are more digits.
// If the first byte is 0x80 (kNumberTerminator), it would normally
@@ -4620,33 +4580,6 @@ int ScriptDataImpl::ReadNumber(byte** source) {
}
-// Create a Scanner for the preparser to use as input, and preparse the source.
-ScriptDataImpl* PreParserApi::PreParse(Isolate* isolate,
- Utf16CharacterStream* source) {
- CompleteParserRecorder recorder;
- HistogramTimerScope timer(isolate->counters()->pre_parse());
- Scanner scanner(isolate->unicode_cache());
- intptr_t stack_limit = isolate->stack_guard()->real_climit();
- PreParser preparser(&scanner, &recorder, stack_limit);
- preparser.set_allow_lazy(true);
- preparser.set_allow_generators(FLAG_harmony_generators);
- preparser.set_allow_for_of(FLAG_harmony_iteration);
- preparser.set_allow_harmony_scoping(FLAG_harmony_scoping);
- preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
- scanner.Initialize(source);
- PreParser::PreParseResult result = preparser.PreParseProgram();
- if (result == PreParser::kPreParseStackOverflow) {
- isolate->StackOverflow();
- return NULL;
- }
-
- // Extract the accumulated data from the recorder as a single
- // contiguous vector that we are responsible for disposing.
- Vector<unsigned> store = recorder.ExtractData();
- return new ScriptDataImpl(store);
-}
-
-
bool RegExpParser::ParseRegExp(FlatStringReader* input,
bool multiline,
RegExpCompileData* result,
@@ -4684,11 +4617,12 @@ bool Parser::Parse() {
SetCachedData(info()->cached_data(), info()->cached_data_mode());
if (info()->cached_data_mode() == CONSUME_CACHED_DATA &&
(*info()->cached_data())->has_error()) {
- ScriptDataImpl* cached_data = *(info()->cached_data());
+ ScriptData* cached_data = *(info()->cached_data());
Scanner::Location loc = cached_data->MessageLocation();
const char* message = cached_data->BuildMessage();
Vector<const char*> args = cached_data->BuildArgs();
- ParserTraits::ReportMessageAt(loc, message, args);
+ ParserTraits::ReportMessageAt(loc, message, args,
+ cached_data->IsReferenceError());
DeleteArray(message);
for (int i = 0; i < args.length(); i++) {
DeleteArray(args[i]);
diff --git a/deps/v8/src/parser.h b/deps/v8/src/parser.h
index f49626766e..71bbfd195d 100644
--- a/deps/v8/src/parser.h
+++ b/deps/v8/src/parser.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PARSER_H_
#define V8_PARSER_H_
@@ -82,17 +59,22 @@ class FunctionEntry BASE_EMBEDDED {
};
-class ScriptDataImpl : public ScriptData {
+class ScriptData {
public:
- explicit ScriptDataImpl(Vector<unsigned> store)
+ explicit ScriptData(Vector<unsigned> store)
: store_(store),
owns_store_(true) { }
- // Create an empty ScriptDataImpl that is guaranteed to not satisfy
- // a SanityCheck.
- ScriptDataImpl() : owns_store_(false) { }
+ ScriptData(Vector<unsigned> store, bool owns_store)
+ : store_(store),
+ owns_store_(owns_store) { }
+
+ // The created ScriptData won't take ownership of the data. If the alignment
+ // is not correct, this will copy the data (and the created ScriptData will
+ // take ownership of the copy).
+ static ScriptData* New(const char* data, int length);
- virtual ~ScriptDataImpl();
+ virtual ~ScriptData();
virtual int Length();
virtual const char* Data();
virtual bool HasError();
@@ -104,14 +86,17 @@ class ScriptDataImpl : public ScriptData {
int GetSymbolIdentifier();
bool SanityCheck();
- Scanner::Location MessageLocation();
- const char* BuildMessage();
- Vector<const char*> BuildArgs();
-
- int symbol_count() {
- return (store_.length() > PreparseDataConstants::kHeaderSize)
- ? store_[PreparseDataConstants::kSymbolCountOffset]
- : 0;
+ Scanner::Location MessageLocation() const;
+ bool IsReferenceError() const;
+ const char* BuildMessage() const;
+ Vector<const char*> BuildArgs() const;
+
+ int function_count() {
+ int functions_size =
+ static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]);
+ if (functions_size < 0) return 0;
+ if (functions_size % FunctionEntry::kSize != 0) return 0;
+ return functions_size / FunctionEntry::kSize;
}
// The following functions should only be called if SanityCheck has
// returned true.
@@ -120,6 +105,10 @@ class ScriptDataImpl : public ScriptData {
unsigned version() { return store_[PreparseDataConstants::kVersionOffset]; }
private:
+ // Disable copying and assigning; because of owns_store they won't be correct.
+ ScriptData(const ScriptData&);
+ ScriptData& operator=(const ScriptData&);
+
friend class v8::ScriptCompiler;
Vector<unsigned> store_;
unsigned char* symbol_data_;
@@ -127,35 +116,13 @@ class ScriptDataImpl : public ScriptData {
int function_index_;
bool owns_store_;
- unsigned Read(int position);
- unsigned* ReadAddress(int position);
+ unsigned Read(int position) const;
+ unsigned* ReadAddress(int position) const;
// Reads a number from the current symbols
int ReadNumber(byte** source);
- ScriptDataImpl(const char* backing_store, int length)
- : store_(reinterpret_cast<unsigned*>(const_cast<char*>(backing_store)),
- length / static_cast<int>(sizeof(unsigned))),
- owns_store_(false) {
- ASSERT_EQ(0, static_cast<int>(
- reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned)));
- }
-
// Read strings written by ParserRecorder::WriteString.
static const char* ReadString(unsigned* start, int* chars);
-
- friend class ScriptData;
-};
-
-
-class PreParserApi {
- public:
- // Pre-parse a character stream and return full preparse data.
- //
- // This interface is here instead of in preparser.h because it instantiates a
- // preparser recorder object that is suited to the parser's purposes. Also,
- // the preparser doesn't know about ScriptDataImpl.
- static ScriptDataImpl* PreParse(Isolate* isolate,
- Utf16CharacterStream* source);
};
@@ -430,6 +397,7 @@ class ParserTraits {
typedef ObjectLiteral::Property* ObjectLiteralProperty;
typedef ZoneList<v8::internal::Expression*>* ExpressionList;
typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
+ typedef ZoneList<v8::internal::Statement*>* StatementList;
// For constructing objects returned by the traversing functions.
typedef AstNodeFactory<AstConstructionVisitor> Factory;
@@ -441,16 +409,14 @@ class ParserTraits {
template<typename FunctionState>
static void SetUpFunctionState(FunctionState* function_state, Zone* zone) {
Isolate* isolate = zone->isolate();
- function_state->isolate_ = isolate;
function_state->saved_ast_node_id_ = isolate->ast_node_id();
isolate->set_ast_node_id(BailoutId::FirstUsable().ToInt());
}
template<typename FunctionState>
- static void TearDownFunctionState(FunctionState* function_state) {
+ static void TearDownFunctionState(FunctionState* function_state, Zone* zone) {
if (function_state->outer_function_state_ != NULL) {
- function_state->isolate_->set_ast_node_id(
- function_state->saved_ast_node_id_);
+ zone->isolate()->set_ast_node_id(function_state->saved_ast_node_id_);
}
}
@@ -462,6 +428,11 @@ class ParserTraits {
static bool IsIdentifier(Expression* expression);
+ static Handle<String> AsIdentifier(Expression* expression) {
+ ASSERT(IsIdentifier(expression));
+ return expression->AsVariableProxy()->name();
+ }
+
static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
return ObjectLiteral::IsBoilerplateProperty(property);
}
@@ -501,10 +472,6 @@ class ParserTraits {
// used on for the statically checking assignments to harmony const bindings.
static Expression* MarkExpressionAsLValue(Expression* expression);
- // Checks LHS expression for assignment and prefix/postfix increment/decrement
- // in strict mode.
- void CheckStrictModeLValue(Expression* expression, bool* ok);
-
// Returns true if we have a binary expression between two numeric
// literals. In that case, *x will be changed to an expression which is the
// computed value.
@@ -527,6 +494,24 @@ class ParserTraits {
Expression* expression, Token::Value op, int pos,
AstNodeFactory<AstConstructionVisitor>* factory);
+ // Generate AST node that throws a ReferenceError with the given type.
+ Expression* NewThrowReferenceError(const char* type, int pos);
+
+ // Generate AST node that throws a SyntaxError with the given
+ // type. The first argument may be null (in the handle sense) in
+ // which case no arguments are passed to the constructor.
+ Expression* NewThrowSyntaxError(
+ const char* type, Handle<Object> arg, int pos);
+
+ // Generate AST node that throws a TypeError with the given
+ // type. Both arguments must be non-null (in the handle sense).
+ Expression* NewThrowTypeError(const char* type, Handle<Object> arg, int pos);
+
+ // Generic AST generator for throwing errors from compiled code.
+ Expression* NewThrowError(
+ Handle<String> constructor, const char* type,
+ Vector<Handle<Object> > arguments, int pos);
+
// Reporting errors.
void ReportMessageAt(Scanner::Location source_location,
const char* message,
@@ -580,6 +565,9 @@ class ParserTraits {
ZoneList<ObjectLiteral::Property*>* NewPropertyList(int size, Zone* zone) {
return new(zone) ZoneList<ObjectLiteral::Property*>(size, zone);
}
+ ZoneList<v8::internal::Statement*>* NewStatementList(int size, Zone* zone) {
+ return new(zone) ZoneList<v8::internal::Statement*>(size, zone);
+ }
// Temporary glue; these functions will move to ParserBase.
Expression* ParseV8Intrinsic(bool* ok);
@@ -655,9 +643,9 @@ class Parser : public ParserBase<ParserTraits> {
Handle<String> source);
// Report syntax error
- void ReportInvalidPreparseData(Handle<String> name, bool* ok);
+ void ReportInvalidCachedData(Handle<String> name, bool* ok);
- void SetCachedData(ScriptDataImpl** data,
+ void SetCachedData(ScriptData** data,
CachedDataMode cached_data_mode) {
cached_data_mode_ = cached_data_mode;
if (cached_data_mode == NO_CACHED_DATA) {
@@ -665,12 +653,11 @@ class Parser : public ParserBase<ParserTraits> {
} else {
ASSERT(data != NULL);
cached_data_ = data;
- symbol_cache_.Initialize(*data ? (*data)->symbol_count() : 0, zone());
}
}
bool inside_with() const { return scope_->inside_with(); }
- ScriptDataImpl** cached_data() const { return cached_data_; }
+ ScriptData** cached_data() const { return cached_data_; }
CachedDataMode cached_data_mode() const { return cached_data_mode_; }
Scope* DeclarationScope(VariableMode mode) {
return IsLexicalVariableMode(mode)
@@ -776,39 +763,32 @@ class Parser : public ParserBase<ParserTraits> {
Scope* NewScope(Scope* parent, ScopeType type);
- Handle<String> LookupCachedSymbol(int symbol_id);
+ // Skip over a lazy function, either using cached data if we have it, or
+ // by parsing the function with PreParser. Consumes the ending }.
+ void SkipLazyFunctionBody(Handle<String> function_name,
+ int* materialized_literal_count,
+ int* expected_property_count,
+ bool* ok);
- // Generate AST node that throw a ReferenceError with the given type.
- Expression* NewThrowReferenceError(Handle<String> type);
-
- // Generate AST node that throw a SyntaxError with the given
- // type. The first argument may be null (in the handle sense) in
- // which case no arguments are passed to the constructor.
- Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first);
-
- // Generate AST node that throw a TypeError with the given
- // type. Both arguments must be non-null (in the handle sense).
- Expression* NewThrowTypeError(Handle<String> type,
- Handle<Object> first,
- Handle<Object> second);
-
- // Generic AST generator for throwing errors from compiled code.
- Expression* NewThrowError(Handle<String> constructor,
- Handle<String> type,
- Vector< Handle<Object> > arguments);
+ PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser(
+ SingletonLogger* logger);
- PreParser::PreParseResult LazyParseFunctionLiteral(
- SingletonLogger* logger);
+ // Consumes the ending }.
+ ZoneList<Statement*>* ParseEagerFunctionBody(Handle<String> function_name,
+ int pos,
+ Variable* fvar,
+ Token::Value fvar_init_op,
+ bool is_generator,
+ bool* ok);
Isolate* isolate_;
- ZoneList<Handle<String> > symbol_cache_;
Handle<Script> script_;
Scanner scanner_;
PreParser* reusable_preparser_;
Scope* original_scope_; // for ES5 function declarations in sloppy eval
Target* target_stack_; // for break, continue statements
- ScriptDataImpl** cached_data_;
+ ScriptData** cached_data_;
CachedDataMode cached_data_mode_;
CompilationInfo* info_;
diff --git a/deps/v8/src/platform-cygwin.cc b/deps/v8/src/platform-cygwin.cc
index 4ae9bec9ec..05ce578270 100644
--- a/deps/v8/src/platform-cygwin.cc
+++ b/deps/v8/src/platform-cygwin.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Platform-specific code for Cygwin goes here. For the POSIX-compatible
// parts, the implementation is in platform-posix.cc.
@@ -42,9 +19,7 @@
#include "v8.h"
#include "platform.h"
-#include "simulator.h"
#include "v8threads.h"
-#include "vm-state-inl.h"
#include "win32-headers.h"
namespace v8 {
diff --git a/deps/v8/src/platform-freebsd.cc b/deps/v8/src/platform-freebsd.cc
index 7d15cef6b0..7e5bb8a9f9 100644
--- a/deps/v8/src/platform-freebsd.cc
+++ b/deps/v8/src/platform-freebsd.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Platform-specific code for FreeBSD goes here. For the POSIX-compatible
// parts, the implementation is in platform-posix.cc.
@@ -54,7 +31,6 @@
#include "v8threads.h"
#include "platform.h"
-#include "vm-state-inl.h"
namespace v8 {
diff --git a/deps/v8/src/platform-linux.cc b/deps/v8/src/platform-linux.cc
index 527b9f616d..34e8c551ef 100644
--- a/deps/v8/src/platform-linux.cc
+++ b/deps/v8/src/platform-linux.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Platform-specific code for Linux goes here. For the POSIX-compatible
// parts, the implementation is in platform-posix.cc.
@@ -68,7 +45,6 @@
#include "platform.h"
#include "v8threads.h"
-#include "vm-state-inl.h"
namespace v8 {
diff --git a/deps/v8/src/platform-macos.cc b/deps/v8/src/platform-macos.cc
index 25ba0da087..facb6bd617 100644
--- a/deps/v8/src/platform-macos.cc
+++ b/deps/v8/src/platform-macos.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Platform-specific code for MacOS goes here. For the POSIX-compatible
// parts, the implementation is in platform-posix.cc.
@@ -59,8 +36,6 @@
#include "v8.h"
#include "platform.h"
-#include "simulator.h"
-#include "vm-state-inl.h"
namespace v8 {
diff --git a/deps/v8/src/platform-openbsd.cc b/deps/v8/src/platform-openbsd.cc
index a5d477d614..21fe2b4d99 100644
--- a/deps/v8/src/platform-openbsd.cc
+++ b/deps/v8/src/platform-openbsd.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Platform-specific code for OpenBSD and NetBSD goes here. For the
// POSIX-compatible parts, the implementation is in platform-posix.cc.
@@ -52,7 +29,6 @@
#include "platform.h"
#include "v8threads.h"
-#include "vm-state-inl.h"
namespace v8 {
diff --git a/deps/v8/src/platform-posix.cc b/deps/v8/src/platform-posix.cc
index 5ca12522c1..143bf3ca10 100644
--- a/deps/v8/src/platform-posix.cc
+++ b/deps/v8/src/platform-posix.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Platform-specific code for POSIX goes here. This is not a platform on its
// own, but contains the parts which are the same across the POSIX platforms
@@ -66,7 +43,6 @@
#include "v8.h"
-#include "codegen.h"
#include "isolate-inl.h"
#include "platform.h"
@@ -96,6 +72,12 @@ intptr_t OS::MaxVirtualMemory() {
struct rlimit limit;
int result = getrlimit(RLIMIT_DATA, &limit);
if (result != 0) return 0;
+#if V8_OS_NACL
+ // The NaCl compiler doesn't like resource.h constants.
+ if (static_cast<int>(limit.rlim_cur) == -1) return 0;
+#else
+ if (limit.rlim_cur == RLIM_INFINITY) return 0;
+#endif
return limit.rlim_cur;
}
@@ -214,6 +196,11 @@ void* OS::GetRandomMmapAddr() {
// See http://code.google.com/p/nativeclient/issues/3341
return NULL;
#endif
+#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
+ defined(THREAD_SANITIZER)
+ // Dynamic tools do not support custom mmap addresses.
+ return NULL;
+#endif
Isolate* isolate = Isolate::UncheckedCurrent();
// Note that the current isolate isn't set up in a call path via
// CpuFeatures::Probe. We don't care about randomization in this case because
@@ -297,33 +284,6 @@ void OS::DebugBreak() {
// ----------------------------------------------------------------------------
// Math functions
-double modulo(double x, double y) {
- return std::fmod(x, y);
-}
-
-
-#define UNARY_MATH_FUNCTION(name, generator) \
-static UnaryMathFunction fast_##name##_function = NULL; \
-void init_fast_##name##_function() { \
- fast_##name##_function = generator; \
-} \
-double fast_##name(double x) { \
- return (*fast_##name##_function)(x); \
-}
-
-UNARY_MATH_FUNCTION(exp, CreateExpFunction())
-UNARY_MATH_FUNCTION(sqrt, CreateSqrtFunction())
-
-#undef UNARY_MATH_FUNCTION
-
-
-void lazily_initialize_fast_exp() {
- if (fast_exp_function == NULL) {
- init_fast_exp_function();
- }
-}
-
-
double OS::nan_value() {
// NAN from math.h is defined in C99 and not in POSIX.
return NAN;
@@ -553,8 +513,6 @@ void OS::PostSetUp() {
OS::memcopy_uint8_function =
CreateMemCopyUint8Function(&OS::MemCopyUint8Wrapper);
#endif
- // fast_exp is initialized lazily.
- init_fast_sqrt_function();
}
diff --git a/deps/v8/src/platform-qnx.cc b/deps/v8/src/platform-qnx.cc
index ef0998f89a..587a1d3554 100644
--- a/deps/v8/src/platform-qnx.cc
+++ b/deps/v8/src/platform-qnx.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Platform-specific code for QNX goes here. For the POSIX-compatible
// parts the implementation is in platform-posix.cc.
@@ -56,7 +33,6 @@
#include "platform.h"
#include "v8threads.h"
-#include "vm-state-inl.h"
namespace v8 {
diff --git a/deps/v8/src/platform-solaris.cc b/deps/v8/src/platform-solaris.cc
index f23ae0838b..a2226f6135 100644
--- a/deps/v8/src/platform-solaris.cc
+++ b/deps/v8/src/platform-solaris.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Platform-specific code for Solaris 10 goes here. For the POSIX-compatible
// parts, the implementation is in platform-posix.cc.
@@ -53,7 +30,6 @@
#include "platform.h"
#include "v8threads.h"
-#include "vm-state-inl.h"
// It seems there is a bug in some Solaris distributions (experienced in
diff --git a/deps/v8/src/platform-win32.cc b/deps/v8/src/platform-win32.cc
index fe84bcd3ff..08d03e1490 100644
--- a/deps/v8/src/platform-win32.cc
+++ b/deps/v8/src/platform-win32.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Platform-specific code for Win32.
@@ -42,11 +19,8 @@
#include "v8.h"
-#include "codegen.h"
#include "isolate-inl.h"
#include "platform.h"
-#include "simulator.h"
-#include "vm-state-inl.h"
#ifdef _MSC_VER
@@ -155,68 +129,6 @@ void OS::MemMove(void* dest, const void* src, size_t size) {
#endif // V8_TARGET_ARCH_IA32
-#ifdef _WIN64
-typedef double (*ModuloFunction)(double, double);
-static ModuloFunction modulo_function = NULL;
-// Defined in codegen-x64.cc.
-ModuloFunction CreateModuloFunction();
-
-void init_modulo_function() {
- modulo_function = CreateModuloFunction();
-}
-
-
-double modulo(double x, double y) {
- // Note: here we rely on dependent reads being ordered. This is true
- // on all architectures we currently support.
- return (*modulo_function)(x, y);
-}
-#else // Win32
-
-double modulo(double x, double y) {
- // Workaround MS fmod bugs. ECMA-262 says:
- // dividend is finite and divisor is an infinity => result equals dividend
- // dividend is a zero and divisor is nonzero finite => result equals dividend
- if (!(std::isfinite(x) && (!std::isfinite(y) && !std::isnan(y))) &&
- !(x == 0 && (y != 0 && std::isfinite(y)))) {
- x = fmod(x, y);
- }
- return x;
-}
-
-#endif // _WIN64
-
-
-#define UNARY_MATH_FUNCTION(name, generator) \
-static UnaryMathFunction fast_##name##_function = NULL; \
-void init_fast_##name##_function() { \
- fast_##name##_function = generator; \
-} \
-double fast_##name(double x) { \
- return (*fast_##name##_function)(x); \
-}
-
-UNARY_MATH_FUNCTION(exp, CreateExpFunction())
-UNARY_MATH_FUNCTION(sqrt, CreateSqrtFunction())
-
-#undef UNARY_MATH_FUNCTION
-
-
-void lazily_initialize_fast_exp() {
- if (fast_exp_function == NULL) {
- init_fast_exp_function();
- }
-}
-
-
-void MathSetup() {
-#ifdef _WIN64
- init_modulo_function();
-#endif
- // fast_exp is initialized lazily.
- init_fast_sqrt_function();
-}
-
class TimezoneCache {
public:
@@ -541,9 +453,6 @@ char* Win32Time::LocalTimezone(TimezoneCache* cache) {
void OS::PostSetUp() {
- // Math functions depend on CPU features therefore they are initialized after
- // CPU.
- MathSetup();
#if V8_TARGET_ARCH_IA32
OS::MemMoveFunction generated_memmove = CreateMemMoveFunction();
if (generated_memmove != NULL) {
diff --git a/deps/v8/src/platform.h b/deps/v8/src/platform.h
index d087d2397d..764bd5408f 100644
--- a/deps/v8/src/platform.h
+++ b/deps/v8/src/platform.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This module contains the platform-specific code. This make the rest of the
// code less dependent on operating system, compilers and runtime libraries.
@@ -48,7 +25,7 @@
#include "platform/mutex.h"
#include "platform/semaphore.h"
-#include "utils.h"
+#include "vector.h"
#include "v8globals.h"
#ifdef __sun
@@ -96,15 +73,6 @@ inline int lrint(double flt) {
namespace v8 {
namespace internal {
-double modulo(double x, double y);
-
-// Custom implementation of math functions.
-double fast_exp(double input);
-double fast_sqrt(double input);
-// The custom exp implementation needs 16KB of lookup data; initialize it
-// on demand.
-void lazily_initialize_fast_exp();
-
// ----------------------------------------------------------------------------
// Fast TLS support
diff --git a/deps/v8/src/platform/condition-variable.cc b/deps/v8/src/platform/condition-variable.cc
index 83c35d4b1b..8e4d16a29e 100644
--- a/deps/v8/src/platform/condition-variable.cc
+++ b/deps/v8/src/platform/condition-variable.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "platform/condition-variable.h"
diff --git a/deps/v8/src/platform/condition-variable.h b/deps/v8/src/platform/condition-variable.h
index 4d8a88aee7..eb357beb3f 100644
--- a/deps/v8/src/platform/condition-variable.h
+++ b/deps/v8/src/platform/condition-variable.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PLATFORM_CONDITION_VARIABLE_H_
#define V8_PLATFORM_CONDITION_VARIABLE_H_
diff --git a/deps/v8/src/platform/elapsed-timer.h b/deps/v8/src/platform/elapsed-timer.h
index b61b007605..b25ff20401 100644
--- a/deps/v8/src/platform/elapsed-timer.h
+++ b/deps/v8/src/platform/elapsed-timer.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PLATFORM_ELAPSED_TIMER_H_
#define V8_PLATFORM_ELAPSED_TIMER_H_
diff --git a/deps/v8/src/platform/mutex.cc b/deps/v8/src/platform/mutex.cc
index ff4a8a3790..4e9fb989b6 100644
--- a/deps/v8/src/platform/mutex.cc
+++ b/deps/v8/src/platform/mutex.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "platform/mutex.h"
diff --git a/deps/v8/src/platform/mutex.h b/deps/v8/src/platform/mutex.h
index 125e9d4860..4abf7f71cd 100644
--- a/deps/v8/src/platform/mutex.h
+++ b/deps/v8/src/platform/mutex.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PLATFORM_MUTEX_H_
#define V8_PLATFORM_MUTEX_H_
diff --git a/deps/v8/src/platform/semaphore.cc b/deps/v8/src/platform/semaphore.cc
index 0b82d4ad57..eae47cb367 100644
--- a/deps/v8/src/platform/semaphore.cc
+++ b/deps/v8/src/platform/semaphore.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "platform/semaphore.h"
diff --git a/deps/v8/src/platform/semaphore.h b/deps/v8/src/platform/semaphore.h
index 0babe5fd65..4344192047 100644
--- a/deps/v8/src/platform/semaphore.h
+++ b/deps/v8/src/platform/semaphore.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PLATFORM_SEMAPHORE_H_
#define V8_PLATFORM_SEMAPHORE_H_
diff --git a/deps/v8/src/platform/socket.cc b/deps/v8/src/platform/socket.cc
index 9d56cc79a8..f4b33873b4 100644
--- a/deps/v8/src/platform/socket.cc
+++ b/deps/v8/src/platform/socket.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "platform/socket.h"
diff --git a/deps/v8/src/platform/socket.h b/deps/v8/src/platform/socket.h
index ff8c1de7ce..8605ae0fa9 100644
--- a/deps/v8/src/platform/socket.h
+++ b/deps/v8/src/platform/socket.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PLATFORM_SOCKET_H_
#define V8_PLATFORM_SOCKET_H_
diff --git a/deps/v8/src/platform/time.cc b/deps/v8/src/platform/time.cc
index 5374af802f..c6b5786a6f 100644
--- a/deps/v8/src/platform/time.cc
+++ b/deps/v8/src/platform/time.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "platform/time.h"
diff --git a/deps/v8/src/platform/time.h b/deps/v8/src/platform/time.h
index 99a8d39318..8e35b87917 100644
--- a/deps/v8/src/platform/time.h
+++ b/deps/v8/src/platform/time.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PLATFORM_TIME_H_
#define V8_PLATFORM_TIME_H_
diff --git a/deps/v8/src/preparse-data-format.h b/deps/v8/src/preparse-data-format.h
index e2cf0a1a3e..4d1ad7abbf 100644
--- a/deps/v8/src/preparse-data-format.h
+++ b/deps/v8/src/preparse-data-format.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PREPARSE_DATA_FORMAT_H_
#define V8_PREPARSE_DATA_FORMAT_H_
@@ -37,21 +14,21 @@ struct PreparseDataConstants {
public:
// Layout and constants of the preparse data exchange format.
static const unsigned kMagicNumber = 0xBadDead;
- static const unsigned kCurrentVersion = 8;
+ static const unsigned kCurrentVersion = 9;
static const int kMagicOffset = 0;
static const int kVersionOffset = 1;
static const int kHasErrorOffset = 2;
static const int kFunctionsSizeOffset = 3;
- static const int kSymbolCountOffset = 4;
- static const int kSizeOffset = 5;
- static const int kHeaderSize = 6;
+ static const int kSizeOffset = 4;
+ static const int kHeaderSize = 5;
// If encoding a message, the following positions are fixed.
static const int kMessageStartPos = 0;
static const int kMessageEndPos = 1;
static const int kMessageArgCountPos = 2;
- static const int kMessageTextPos = 3;
+ static const int kIsReferenceErrorPos = 3;
+ static const int kMessageTextPos = 4;
static const unsigned char kNumberTerminator = 0x80u;
};
diff --git a/deps/v8/src/preparse-data.cc b/deps/v8/src/preparse-data.cc
index 9f585a991f..5ddf72137f 100644
--- a/deps/v8/src/preparse-data.cc
+++ b/deps/v8/src/preparse-data.cc
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "../include/v8stdint.h"
@@ -38,59 +15,27 @@ namespace v8 {
namespace internal {
-template <typename Char>
-static int vector_hash(Vector<const Char> string) {
- int hash = 0;
- for (int i = 0; i < string.length(); i++) {
- int c = static_cast<int>(string[i]);
- hash += c;
- hash += (hash << 10);
- hash ^= (hash >> 6);
- }
- return hash;
-}
-
-
-static bool vector_compare(void* a, void* b) {
- CompleteParserRecorder::Key* string1 =
- reinterpret_cast<CompleteParserRecorder::Key*>(a);
- CompleteParserRecorder::Key* string2 =
- reinterpret_cast<CompleteParserRecorder::Key*>(b);
- if (string1->is_one_byte != string2->is_one_byte) return false;
- int length = string1->literal_bytes.length();
- if (string2->literal_bytes.length() != length) return false;
- return memcmp(string1->literal_bytes.start(),
- string2->literal_bytes.start(), length) == 0;
-}
-
-
CompleteParserRecorder::CompleteParserRecorder()
- : function_store_(0),
- literal_chars_(0),
- symbol_store_(0),
- symbol_keys_(0),
- string_table_(vector_compare),
- symbol_id_(0) {
+ : function_store_(0) {
preamble_[PreparseDataConstants::kMagicOffset] =
PreparseDataConstants::kMagicNumber;
preamble_[PreparseDataConstants::kVersionOffset] =
PreparseDataConstants::kCurrentVersion;
preamble_[PreparseDataConstants::kHasErrorOffset] = false;
preamble_[PreparseDataConstants::kFunctionsSizeOffset] = 0;
- preamble_[PreparseDataConstants::kSymbolCountOffset] = 0;
preamble_[PreparseDataConstants::kSizeOffset] = 0;
- ASSERT_EQ(6, PreparseDataConstants::kHeaderSize);
+ ASSERT_EQ(5, PreparseDataConstants::kHeaderSize);
#ifdef DEBUG
prev_start_ = -1;
#endif
- should_log_symbols_ = true;
}
void CompleteParserRecorder::LogMessage(int start_pos,
- int end_pos,
- const char* message,
- const char* arg_opt) {
+ int end_pos,
+ const char* message,
+ const char* arg_opt,
+ bool is_reference_error) {
if (has_error()) return;
preamble_[PreparseDataConstants::kHasErrorOffset] = true;
function_store_.Reset();
@@ -100,10 +45,11 @@ void CompleteParserRecorder::LogMessage(int start_pos,
function_store_.Add(end_pos);
STATIC_ASSERT(PreparseDataConstants::kMessageArgCountPos == 2);
function_store_.Add((arg_opt == NULL) ? 0 : 1);
- STATIC_ASSERT(PreparseDataConstants::kMessageTextPos == 3);
+ STATIC_ASSERT(PreparseDataConstants::kIsReferenceErrorPos == 3);
+ function_store_.Add(is_reference_error ? 1 : 0);
+ STATIC_ASSERT(PreparseDataConstants::kMessageTextPos == 4);
WriteString(CStrVector(message));
if (arg_opt != NULL) WriteString(CStrVector(arg_opt));
- should_log_symbols_ = false;
}
@@ -115,92 +61,18 @@ void CompleteParserRecorder::WriteString(Vector<const char> str) {
}
-void CompleteParserRecorder::LogOneByteSymbol(int start,
- Vector<const uint8_t> literal) {
- ASSERT(should_log_symbols_);
- int hash = vector_hash(literal);
- LogSymbol(start, hash, true, literal);
-}
-
-
-void CompleteParserRecorder::LogTwoByteSymbol(int start,
- Vector<const uint16_t> literal) {
- ASSERT(should_log_symbols_);
- int hash = vector_hash(literal);
- LogSymbol(start, hash, false, Vector<const byte>::cast(literal));
-}
-
-
-void CompleteParserRecorder::LogSymbol(int start,
- int hash,
- bool is_one_byte,
- Vector<const byte> literal_bytes) {
- Key key = { is_one_byte, literal_bytes };
- HashMap::Entry* entry = string_table_.Lookup(&key, hash, true);
- int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
- if (id == 0) {
- // Copy literal contents for later comparison.
- key.literal_bytes =
- Vector<const byte>::cast(literal_chars_.AddBlock(literal_bytes));
- // Put (symbol_id_ + 1) into entry and increment it.
- id = ++symbol_id_;
- entry->value = reinterpret_cast<void*>(id);
- Vector<Key> symbol = symbol_keys_.AddBlock(1, key);
- entry->key = &symbol[0];
- }
- WriteNumber(id - 1);
-}
-
-
Vector<unsigned> CompleteParserRecorder::ExtractData() {
int function_size = function_store_.size();
- // Add terminator to symbols, then pad to unsigned size.
- int symbol_size = symbol_store_.size();
- int padding = sizeof(unsigned) - (symbol_size % sizeof(unsigned));
- symbol_store_.AddBlock(padding, PreparseDataConstants::kNumberTerminator);
- symbol_size += padding;
- int total_size = PreparseDataConstants::kHeaderSize + function_size
- + (symbol_size / sizeof(unsigned));
+ int total_size = PreparseDataConstants::kHeaderSize + function_size;
Vector<unsigned> data = Vector<unsigned>::New(total_size);
preamble_[PreparseDataConstants::kFunctionsSizeOffset] = function_size;
- preamble_[PreparseDataConstants::kSymbolCountOffset] = symbol_id_;
OS::MemCopy(data.start(), preamble_, sizeof(preamble_));
- int symbol_start = PreparseDataConstants::kHeaderSize + function_size;
if (function_size > 0) {
function_store_.WriteTo(data.SubVector(PreparseDataConstants::kHeaderSize,
- symbol_start));
- }
- if (!has_error()) {
- symbol_store_.WriteTo(
- Vector<byte>::cast(data.SubVector(symbol_start, total_size)));
+ total_size));
}
return data;
}
-void CompleteParserRecorder::WriteNumber(int number) {
- // Split the number into chunks of 7 bits. Write them one after another (the
- // most significant first). Use the MSB of each byte for signalling that the
- // number continues. See ScriptDataImpl::ReadNumber for the reading side.
- ASSERT(number >= 0);
-
- int mask = (1 << 28) - 1;
- int i = 28;
- // 26 million symbols ought to be enough for anybody.
- ASSERT(number <= mask);
- while (number < mask) {
- mask >>= 7;
- i -= 7;
- }
- while (i > 0) {
- symbol_store_.Add(static_cast<byte>(number >> i) | 0x80u);
- number &= mask;
- mask >>= 7;
- i -= 7;
- }
- ASSERT(number < (1 << 7));
- symbol_store_.Add(static_cast<byte>(number));
-}
-
-
} } // namespace v8::internal.
diff --git a/deps/v8/src/preparse-data.h b/deps/v8/src/preparse-data.h
index 6a968e3b22..051a909690 100644
--- a/deps/v8/src/preparse-data.h
+++ b/deps/v8/src/preparse-data.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PREPARSE_DATA_H_
#define V8_PREPARSE_DATA_H_
@@ -39,7 +16,7 @@ namespace internal {
// Abstract interface for preparse data recorder.
class ParserRecorder {
public:
- ParserRecorder() : should_log_symbols_(false) { }
+ ParserRecorder() { }
virtual ~ParserRecorder() { }
// Logs the scope and some details of a function literal in the source.
@@ -55,24 +32,8 @@ class ParserRecorder {
virtual void LogMessage(int start,
int end,
const char* message,
- const char* argument_opt) = 0;
-
- // Logs a symbol creation of a literal or identifier.
- bool ShouldLogSymbols() { return should_log_symbols_; }
- // The following functions are only callable on CompleteParserRecorder
- // and are guarded by calls to ShouldLogSymbols.
- virtual void LogOneByteSymbol(int start, Vector<const uint8_t> literal) {
- UNREACHABLE();
- }
- virtual void LogTwoByteSymbol(int start, Vector<const uint16_t> literal) {
- UNREACHABLE();
- }
- virtual void PauseRecording() { UNREACHABLE(); }
- virtual void ResumeRecording() { UNREACHABLE(); }
-
- protected:
- bool should_log_symbols_;
-
+ const char* argument_opt,
+ bool is_reference_error) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(ParserRecorder);
};
@@ -80,8 +41,9 @@ class ParserRecorder {
class SingletonLogger : public ParserRecorder {
public:
- SingletonLogger() : has_error_(false), start_(-1), end_(-1) { }
- virtual ~SingletonLogger() { }
+ SingletonLogger()
+ : has_error_(false), start_(-1), end_(-1), is_reference_error_(false) {}
+ virtual ~SingletonLogger() {}
void Reset() { has_error_ = false; }
@@ -104,36 +66,39 @@ class SingletonLogger : public ParserRecorder {
virtual void LogMessage(int start,
int end,
const char* message,
- const char* argument_opt) {
+ const char* argument_opt,
+ bool is_reference_error) {
if (has_error_) return;
has_error_ = true;
start_ = start;
end_ = end;
message_ = message;
argument_opt_ = argument_opt;
+ is_reference_error_ = is_reference_error;
}
- bool has_error() { return has_error_; }
+ bool has_error() const { return has_error_; }
- int start() { return start_; }
- int end() { return end_; }
- int literals() {
+ int start() const { return start_; }
+ int end() const { return end_; }
+ int literals() const {
ASSERT(!has_error_);
return literals_;
}
- int properties() {
+ int properties() const {
ASSERT(!has_error_);
return properties_;
}
- StrictMode strict_mode() {
+ StrictMode strict_mode() const {
ASSERT(!has_error_);
return strict_mode_;
}
+ int is_reference_error() const { return is_reference_error_; }
const char* message() {
ASSERT(has_error_);
return message_;
}
- const char* argument_opt() {
+ const char* argument_opt() const {
ASSERT(has_error_);
return argument_opt_;
}
@@ -149,6 +114,7 @@ class SingletonLogger : public ParserRecorder {
// For error messages.
const char* message_;
const char* argument_opt_;
+ bool is_reference_error_;
};
@@ -180,20 +146,8 @@ class CompleteParserRecorder : public ParserRecorder {
virtual void LogMessage(int start,
int end,
const char* message,
- const char* argument_opt);
-
- virtual void PauseRecording() {
- ASSERT(should_log_symbols_);
- should_log_symbols_ = false;
- }
-
- virtual void ResumeRecording() {
- ASSERT(!should_log_symbols_);
- should_log_symbols_ = !has_error();
- }
-
- virtual void LogOneByteSymbol(int start, Vector<const uint8_t> literal);
- virtual void LogTwoByteSymbol(int start, Vector<const uint16_t> literal);
+ const char* argument_opt,
+ bool is_reference_error_);
Vector<unsigned> ExtractData();
private:
@@ -203,14 +157,6 @@ class CompleteParserRecorder : public ParserRecorder {
void WriteString(Vector<const char> str);
- // For testing. Defined in test-parsing.cc.
- friend struct CompleteParserRecorderFriend;
-
- void LogSymbol(int start,
- int hash,
- bool is_one_byte,
- Vector<const byte> literal);
-
// Write a non-negative number to the symbol store.
void WriteNumber(int number);
@@ -220,12 +166,6 @@ class CompleteParserRecorder : public ParserRecorder {
#ifdef DEBUG
int prev_start_;
#endif
-
- Collector<byte> literal_chars_;
- Collector<byte> symbol_store_;
- Collector<Key> symbol_keys_;
- HashMap string_table_;
- int symbol_id_;
};
diff --git a/deps/v8/src/preparser.cc b/deps/v8/src/preparser.cc
index 9bcc88002d..96623b9526 100644
--- a/deps/v8/src/preparser.cc
+++ b/deps/v8/src/preparser.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <cmath>
@@ -56,17 +33,6 @@ namespace v8 {
namespace internal {
-void PreParserTraits::CheckStrictModeLValue(PreParserExpression expression,
- bool* ok) {
- if (expression.IsIdentifier() &&
- expression.AsIdentifier().IsEvalOrArguments()) {
- pre_parser_->ReportMessage("strict_eval_arguments",
- Vector<const char*>::empty());
- *ok = false;
- }
-}
-
-
void PreParserTraits::ReportMessageAt(Scanner::Location location,
const char* message,
Vector<const char*> args,
@@ -83,8 +49,8 @@ void PreParserTraits::ReportMessageAt(Scanner::Location location,
const char* type,
const char* name_opt,
bool is_reference_error) {
- pre_parser_->log_
- ->LogMessage(location.beg_pos, location.end_pos, type, name_opt);
+ pre_parser_->log_->LogMessage(location.beg_pos, location.end_pos, type,
+ name_opt, is_reference_error);
}
@@ -93,12 +59,12 @@ void PreParserTraits::ReportMessageAt(int start_pos,
const char* type,
const char* name_opt,
bool is_reference_error) {
- pre_parser_->log_->LogMessage(start_pos, end_pos, type, name_opt);
+ pre_parser_->log_->LogMessage(start_pos, end_pos, type, name_opt,
+ is_reference_error);
}
PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
- pre_parser_->LogSymbol();
if (scanner->current_token() == Token::FUTURE_RESERVED_WORD) {
return PreParserIdentifier::FutureReserved();
} else if (scanner->current_token() ==
@@ -119,7 +85,6 @@ PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
PreParserExpression PreParserTraits::ExpressionFromString(
int pos, Scanner* scanner, PreParserFactory* factory) {
- pre_parser_->LogSymbol();
if (scanner->UnescapedLiteralMatches("use strict", 10)) {
return PreParserExpression::UseStrictStringLiteral();
}
@@ -592,7 +557,7 @@ PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
// ReturnStatement ::
// 'return' [no line terminator] Expression? ';'
- // Consume the return token. It is necessary to do the before
+ // Consume the return token. It is necessary to do before
// reporting any errors on it, because of the way errors are
// reported (underlining).
Expect(Token::RETURN, CHECK_OK);
@@ -942,10 +907,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
int body_start = position();
- bool is_logging = log_->ShouldLogSymbols();
- if (is_logging) log_->PauseRecording();
ParseSourceElements(Token::RBRACE, ok);
- if (is_logging) log_->ResumeRecording();
if (!*ok) return;
// Position right after terminal '}'.
@@ -976,11 +938,4 @@ PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
#undef CHECK_OK
-void PreParser::LogSymbol() {
- if (log_->ShouldLogSymbols()) {
- scanner()->LogSymbol(log_, position());
- }
-}
-
-
} } // v8::internal
diff --git a/deps/v8/src/preparser.h b/deps/v8/src/preparser.h
index 080b772873..6733658579 100644
--- a/deps/v8/src/preparser.h
+++ b/deps/v8/src/preparser.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PREPARSER_H
#define V8_PREPARSER_H
@@ -228,8 +205,8 @@ class ParserBase : public Traits {
FunctionState* outer_function_state_;
typename Traits::Type::Scope** scope_stack_;
typename Traits::Type::Scope* outer_scope_;
- Isolate* isolate_; // Only used by ParserTraits.
int saved_ast_node_id_; // Only used by ParserTraits.
+ typename Traits::Type::Zone* extra_param_;
typename Traits::Type::Factory factory_;
friend class ParserTraits;
@@ -425,6 +402,13 @@ class ParserBase : public Traits {
ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
bool* ok);
+ // Checks if the expression is a valid reference expression (e.g., on the
+ // left-hand side of assignments). Although ruled out by ECMA as early errors,
+ // we allow calls for web compatibility and rewrite them to a runtime throw.
+ ExpressionT CheckAndRewriteReferenceExpression(
+ ExpressionT expression,
+ Scanner::Location location, const char* message, bool* ok);
+
// Used to detect duplicates in object literals. Each of the values
// kGetterProperty, kSetterProperty and kValueProperty represents
// a type of object literal property. When parsing a property, its
@@ -589,10 +573,14 @@ class PreParserExpression {
return PreParserExpression(kPropertyExpression);
}
+ static PreParserExpression Call() {
+ return PreParserExpression(kCallExpression);
+ }
+
bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; }
- // Only works corretly if it is actually an identifier expression.
PreParserIdentifier AsIdentifier() {
+ ASSERT(IsIdentifier());
return PreParserIdentifier(
static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift));
}
@@ -611,13 +599,14 @@ class PreParserExpression {
return code_ == kPropertyExpression || code_ == kThisPropertyExpression;
}
- bool IsValidLeftHandSide() {
+ bool IsCall() { return code_ == kCallExpression; }
+
+ bool IsValidReferenceExpression() {
return IsIdentifier() || IsProperty();
}
// At the moment PreParser doesn't track these expression types.
bool IsFunctionLiteral() const { return false; }
- bool IsCall() const { return false; }
bool IsCallNew() const { return false; }
PreParserExpression AsFunctionLiteral() { return *this; }
@@ -651,7 +640,8 @@ class PreParserExpression {
// 2 least significant bits for flags.
kThisExpression = 1 << 2,
kThisPropertyExpression = 2 << 2,
- kPropertyExpression = 3 << 2
+ kPropertyExpression = 3 << 2,
+ kCallExpression = 4 << 2
};
explicit PreParserExpression(int expression_code) : code_(expression_code) {}
@@ -674,6 +664,67 @@ class PreParserExpressionList {
};
+class PreParserStatement {
+ public:
+ static PreParserStatement Default() {
+ return PreParserStatement(kUnknownStatement);
+ }
+
+ static PreParserStatement FunctionDeclaration() {
+ return PreParserStatement(kFunctionDeclaration);
+ }
+
+ // Creates expression statement from expression.
+ // Preserves being an unparenthesized string literal, possibly
+ // "use strict".
+ static PreParserStatement ExpressionStatement(
+ PreParserExpression expression) {
+ if (expression.IsUseStrictLiteral()) {
+ return PreParserStatement(kUseStrictExpressionStatement);
+ }
+ if (expression.IsStringLiteral()) {
+ return PreParserStatement(kStringLiteralExpressionStatement);
+ }
+ return Default();
+ }
+
+ bool IsStringLiteral() {
+ return code_ == kStringLiteralExpressionStatement;
+ }
+
+ bool IsUseStrictLiteral() {
+ return code_ == kUseStrictExpressionStatement;
+ }
+
+ bool IsFunctionDeclaration() {
+ return code_ == kFunctionDeclaration;
+ }
+
+ private:
+ enum Type {
+ kUnknownStatement,
+ kStringLiteralExpressionStatement,
+ kUseStrictExpressionStatement,
+ kFunctionDeclaration
+ };
+
+ explicit PreParserStatement(Type code) : code_(code) {}
+ Type code_;
+};
+
+
+
+// PreParserStatementList doesn't actually store the statements because
+// the PreParser does not need them.
+class PreParserStatementList {
+ public:
+ // These functions make list->Add(some_expression) work as no-ops.
+ PreParserStatementList() {}
+ PreParserStatementList* operator->() { return this; }
+ void Add(PreParserStatement, void*) {}
+};
+
+
class PreParserScope {
public:
explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type)
@@ -782,7 +833,7 @@ class PreParserFactory {
PreParserExpression NewCall(PreParserExpression expression,
PreParserExpressionList arguments,
int pos) {
- return PreParserExpression::Default();
+ return PreParserExpression::Call();
}
PreParserExpression NewCallNew(PreParserExpression expression,
PreParserExpressionList arguments,
@@ -817,6 +868,7 @@ class PreParserTraits {
typedef PreParserExpression Literal;
typedef PreParserExpressionList ExpressionList;
typedef PreParserExpressionList PropertyList;
+ typedef PreParserStatementList StatementList;
// For constructing objects returned by the traversing functions.
typedef PreParserFactory Factory;
@@ -829,7 +881,7 @@ class PreParserTraits {
template<typename FunctionState>
static void SetUpFunctionState(FunctionState* function_state, void*) {}
template<typename FunctionState>
- static void TearDownFunctionState(FunctionState* function_state) {}
+ static void TearDownFunctionState(FunctionState* function_state, void*) {}
// Helper functions for recursive descent.
static bool IsEvalOrArguments(PreParserIdentifier identifier) {
@@ -845,6 +897,10 @@ class PreParserTraits {
return expression.IsIdentifier();
}
+ static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
+ return expression.AsIdentifier();
+ }
+
static bool IsBoilerplateProperty(PreParserExpression property) {
// PreParser doesn't count boilerplate properties.
return false;
@@ -883,10 +939,6 @@ class PreParserTraits {
return expression;
}
- // Checks LHS expression for assignment and prefix/postfix increment/decrement
- // in strict mode.
- void CheckStrictModeLValue(PreParserExpression expression, bool* ok);
-
bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
PreParserExpression y,
Token::Value op,
@@ -901,6 +953,18 @@ class PreParserTraits {
return PreParserExpression::Default();
}
+ PreParserExpression NewThrowReferenceError(const char* type, int pos) {
+ return PreParserExpression::Default();
+ }
+ PreParserExpression NewThrowSyntaxError(
+ const char* type, Handle<Object> arg, int pos) {
+ return PreParserExpression::Default();
+ }
+ PreParserExpression NewThrowTypeError(
+ const char* type, Handle<Object> arg, int pos) {
+ return PreParserExpression::Default();
+ }
+
// Reporting errors.
void ReportMessageAt(Scanner::Location location,
const char* message,
@@ -968,6 +1032,10 @@ class PreParserTraits {
return PreParserExpressionList();
}
+ static PreParserStatementList NewStatementList(int size, void* zone) {
+ return PreParserStatementList();
+ }
+
static PreParserExpressionList NewPropertyList(int size, void* zone) {
return PreParserExpressionList();
}
@@ -1004,6 +1072,7 @@ class PreParser : public ParserBase<PreParserTraits> {
public:
typedef PreParserIdentifier Identifier;
typedef PreParserExpression Expression;
+ typedef PreParserStatement Statement;
enum PreParseResult {
kPreParseStackOverflow,
@@ -1065,52 +1134,6 @@ class PreParser : public ParserBase<PreParserTraits> {
kHasNoInitializers
};
- class Statement {
- public:
- static Statement Default() {
- return Statement(kUnknownStatement);
- }
-
- static Statement FunctionDeclaration() {
- return Statement(kFunctionDeclaration);
- }
-
- // Creates expression statement from expression.
- // Preserves being an unparenthesized string literal, possibly
- // "use strict".
- static Statement ExpressionStatement(Expression expression) {
- if (expression.IsUseStrictLiteral()) {
- return Statement(kUseStrictExpressionStatement);
- }
- if (expression.IsStringLiteral()) {
- return Statement(kStringLiteralExpressionStatement);
- }
- return Default();
- }
-
- bool IsStringLiteral() {
- return code_ == kStringLiteralExpressionStatement;
- }
-
- bool IsUseStrictLiteral() {
- return code_ == kUseStrictExpressionStatement;
- }
-
- bool IsFunctionDeclaration() {
- return code_ == kFunctionDeclaration;
- }
-
- private:
- enum Type {
- kUnknownStatement,
- kStringLiteralExpressionStatement,
- kUseStrictExpressionStatement,
- kFunctionDeclaration
- };
-
- explicit Statement(Type code) : code_(code) {}
- Type code_;
- };
enum SourceElements {
kUnknownSourceElements
@@ -1158,11 +1181,6 @@ class PreParser : public ParserBase<PreParserTraits> {
bool* ok);
void ParseLazyFunctionLiteralBody(bool* ok);
- // Logs the currently parsed literal as a symbol in the preparser data.
- void LogSymbol();
- // Log the currently parsed string literal.
- Expression GetStringSymbol();
-
bool CheckInOrOf(bool accept_OF);
};
@@ -1181,8 +1199,8 @@ ParserBase<Traits>::FunctionState::FunctionState(
outer_function_state_(*function_state_stack),
scope_stack_(scope_stack),
outer_scope_(*scope_stack),
- isolate_(NULL),
saved_ast_node_id_(0),
+ extra_param_(extra_param),
factory_(extra_param) {
*scope_stack_ = scope;
*function_state_stack = this;
@@ -1194,7 +1212,7 @@ template<class Traits>
ParserBase<Traits>::FunctionState::~FunctionState() {
*scope_stack_ = outer_scope_;
*function_state_stack_ = outer_function_state_;
- Traits::TearDownFunctionState(this);
+ Traits::TearDownFunctionState(this, extra_param_);
}
@@ -1695,16 +1713,8 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
return expression;
}
- if (!expression->IsValidLeftHandSide()) {
- this->ReportMessageAt(lhs_location, "invalid_lhs_in_assignment", true);
- *ok = false;
- return this->EmptyExpression();
- }
-
- if (strict_mode() == STRICT) {
- // Assignment to eval or arguments is disallowed in strict mode.
- this->CheckStrictModeLValue(expression, CHECK_OK);
- }
+ expression = this->CheckAndRewriteReferenceExpression(
+ expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
expression = this->MarkExpressionAsLValue(expression);
Token::Value op = Next(); // Get assignment operator.
@@ -1864,17 +1874,9 @@ ParserBase<Traits>::ParseUnaryExpression(bool* ok) {
} else if (Token::IsCountOp(op)) {
op = Next();
Scanner::Location lhs_location = scanner()->peek_location();
- ExpressionT expression = ParseUnaryExpression(CHECK_OK);
- if (!expression->IsValidLeftHandSide()) {
- ReportMessageAt(lhs_location, "invalid_lhs_in_prefix_op", true);
- *ok = false;
- return this->EmptyExpression();
- }
-
- if (strict_mode() == STRICT) {
- // Prefix expression operand in strict mode may not be eval or arguments.
- this->CheckStrictModeLValue(expression, CHECK_OK);
- }
+ ExpressionT expression = this->ParseUnaryExpression(CHECK_OK);
+ expression = this->CheckAndRewriteReferenceExpression(
+ expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK);
this->MarkExpressionAsLValue(expression);
return factory()->NewCountOperation(op,
@@ -1898,16 +1900,8 @@ ParserBase<Traits>::ParsePostfixExpression(bool* ok) {
ExpressionT expression = this->ParseLeftHandSideExpression(CHECK_OK);
if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
Token::IsCountOp(peek())) {
- if (!expression->IsValidLeftHandSide()) {
- ReportMessageAt(lhs_location, "invalid_lhs_in_postfix_op", true);
- *ok = false;
- return this->EmptyExpression();
- }
-
- if (strict_mode() == STRICT) {
- // Postfix expression operand in strict mode may not be eval or arguments.
- this->CheckStrictModeLValue(expression, CHECK_OK);
- }
+ expression = this->CheckAndRewriteReferenceExpression(
+ expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK);
expression = this->MarkExpressionAsLValue(expression);
Token::Value next = Next();
@@ -2051,7 +2045,7 @@ ParserBase<Traits>::ParseMemberExpression(bool* ok) {
Consume(Token::FUNCTION);
int function_token_position = position();
bool is_generator = allow_generators() && Check(Token::MUL);
- IdentifierT name;
+ IdentifierT name = this->EmptyIdentifier();
bool is_strict_reserved_name = false;
Scanner::Location function_name_location = Scanner::Location::invalid();
FunctionLiteral::FunctionType function_type =
@@ -2117,6 +2111,32 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
}
+template <typename Traits>
+typename ParserBase<Traits>::ExpressionT
+ParserBase<Traits>::CheckAndRewriteReferenceExpression(
+ ExpressionT expression,
+ Scanner::Location location, const char* message, bool* ok) {
+ if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
+ this->IsEvalOrArguments(this->AsIdentifier(expression))) {
+ this->ReportMessageAt(location, "strict_eval_arguments", false);
+ *ok = false;
+ return this->EmptyExpression();
+ } else if (expression->IsValidReferenceExpression()) {
+ return expression;
+ } else if (expression->IsCall()) {
+ // If it is a call, make it a runtime error for legacy web compatibility.
+ // Rewrite `expr' to `expr[throw ReferenceError]'.
+ int pos = location.beg_pos;
+ ExpressionT error = this->NewThrowReferenceError(message, pos);
+ return factory()->NewProperty(expression, error, pos);
+ } else {
+ this->ReportMessageAt(location, message, true);
+ *ok = false;
+ return this->EmptyExpression();
+ }
+}
+
+
#undef CHECK_OK
#undef CHECK_OK_CUSTOM
diff --git a/deps/v8/src/prettyprinter.cc b/deps/v8/src/prettyprinter.cc
index 130fec1b23..233d7c2fab 100644
--- a/deps/v8/src/prettyprinter.cc
+++ b/deps/v8/src/prettyprinter.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <stdarg.h>
diff --git a/deps/v8/src/prettyprinter.h b/deps/v8/src/prettyprinter.h
index a792720fe8..e0467ca82a 100644
--- a/deps/v8/src/prettyprinter.h
+++ b/deps/v8/src/prettyprinter.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PRETTYPRINTER_H_
#define V8_PRETTYPRINTER_H_
diff --git a/deps/v8/src/profile-generator-inl.h b/deps/v8/src/profile-generator-inl.h
index 9aeb8f5c23..9e8408d916 100644
--- a/deps/v8/src/profile-generator-inl.h
+++ b/deps/v8/src/profile-generator-inl.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PROFILE_GENERATOR_INL_H_
#define V8_PROFILE_GENERATOR_INL_H_
diff --git a/deps/v8/src/profile-generator.cc b/deps/v8/src/profile-generator.cc
index 6bd446e0c4..957f5dbae0 100644
--- a/deps/v8/src/profile-generator.cc
+++ b/deps/v8/src/profile-generator.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -355,19 +332,21 @@ void ProfileTree::TraverseDepthFirst(Callback* callback) {
CpuProfile::CpuProfile(const char* title, bool record_samples)
: title_(title),
record_samples_(record_samples),
- start_time_(Time::NowFromSystemTime()) {
- timer_.Start();
+ start_time_(TimeTicks::HighResolutionNow()) {
}
-void CpuProfile::AddPath(const Vector<CodeEntry*>& path) {
+void CpuProfile::AddPath(TimeTicks timestamp, const Vector<CodeEntry*>& path) {
ProfileNode* top_frame_node = top_down_.AddPathFromEnd(path);
- if (record_samples_) samples_.Add(top_frame_node);
+ if (record_samples_) {
+ timestamps_.Add(timestamp);
+ samples_.Add(top_frame_node);
+ }
}
void CpuProfile::CalculateTotalTicksAndSamplingRate() {
- end_time_ = start_time_ + timer_.Elapsed();
+ end_time_ = TimeTicks::HighResolutionNow();
}
@@ -546,13 +525,13 @@ void CpuProfilesCollection::RemoveProfile(CpuProfile* profile) {
void CpuProfilesCollection::AddPathToCurrentProfiles(
- const Vector<CodeEntry*>& path) {
+ TimeTicks timestamp, const Vector<CodeEntry*>& path) {
// As starting / stopping profiles is rare relatively to this
// method, we don't bother minimizing the duration of lock holding,
// e.g. copying contents of the list to a local vector.
current_profiles_semaphore_.Wait();
for (int i = 0; i < current_profiles_.length(); ++i) {
- current_profiles_[i]->AddPath(path);
+ current_profiles_[i]->AddPath(timestamp, path);
}
current_profiles_semaphore_.Signal();
}
@@ -675,7 +654,7 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
}
}
- profiles_->AddPathToCurrentProfiles(entries);
+ profiles_->AddPathToCurrentProfiles(sample.timestamp, entries);
}
diff --git a/deps/v8/src/profile-generator.h b/deps/v8/src/profile-generator.h
index 81980bfc99..1d8ad87cf4 100644
--- a/deps/v8/src/profile-generator.h
+++ b/deps/v8/src/profile-generator.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PROFILE_GENERATOR_H_
#define V8_PROFILE_GENERATOR_H_
@@ -199,7 +176,7 @@ class CpuProfile {
CpuProfile(const char* title, bool record_samples);
// Add pc -> ... -> main() call path to the profile.
- void AddPath(const Vector<CodeEntry*>& path);
+ void AddPath(TimeTicks timestamp, const Vector<CodeEntry*>& path);
void CalculateTotalTicksAndSamplingRate();
const char* title() const { return title_; }
@@ -207,9 +184,10 @@ class CpuProfile {
int samples_count() const { return samples_.length(); }
ProfileNode* sample(int index) const { return samples_.at(index); }
+ TimeTicks sample_timestamp(int index) const { return timestamps_.at(index); }
- Time start_time() const { return start_time_; }
- Time end_time() const { return end_time_; }
+ TimeTicks start_time() const { return start_time_; }
+ TimeTicks end_time() const { return end_time_; }
void UpdateTicksScale();
@@ -218,10 +196,10 @@ class CpuProfile {
private:
const char* title_;
bool record_samples_;
- Time start_time_;
- Time end_time_;
- ElapsedTimer timer_;
+ TimeTicks start_time_;
+ TimeTicks end_time_;
List<ProfileNode*> samples_;
+ List<TimeTicks> timestamps_;
ProfileTree top_down_;
DISALLOW_COPY_AND_ASSIGN(CpuProfile);
@@ -306,7 +284,8 @@ class CpuProfilesCollection {
int column_number = v8::CpuProfileNode::kNoColumnNumberInfo);
// Called from profile generator thread.
- void AddPathToCurrentProfiles(const Vector<CodeEntry*>& path);
+ void AddPathToCurrentProfiles(
+ TimeTicks timestamp, const Vector<CodeEntry*>& path);
// Limits the number of profiles that can be simultaneously collected.
static const int kMaxSimultaneousProfiles = 100;
diff --git a/deps/v8/src/promise.js b/deps/v8/src/promise.js
index 50f91ae0ba..fa650eaf0e 100644
--- a/deps/v8/src/promise.js
+++ b/deps/v8/src/promise.js
@@ -1,30 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
"use strict";
@@ -37,14 +13,17 @@
var $Promise = function Promise(resolver) {
if (resolver === promiseRaw) return;
if (!%_IsConstructCall()) throw MakeTypeError('not_a_promise', [this]);
- if (typeof resolver !== 'function')
+ if (!IS_SPEC_FUNCTION(resolver))
throw MakeTypeError('resolver_not_a_function', [resolver]);
var promise = PromiseInit(this);
try {
+ %DebugPromiseHandlePrologue(function() { return promise });
resolver(function(x) { PromiseResolve(promise, x) },
function(r) { PromiseReject(promise, r) });
} catch (e) {
PromiseReject(promise, e);
+ } finally {
+ %DebugPromiseHandleEpilogue();
}
}
@@ -172,17 +151,20 @@ function PromiseCatch(onReject) {
}
function PromiseEnqueue(value, tasks) {
- GetMicrotaskQueue().push(function() {
+ EnqueueMicrotask(function() {
for (var i = 0; i < tasks.length; i += 2) {
PromiseHandle(value, tasks[i], tasks[i + 1])
}
});
-
- %SetMicrotaskPending(true);
}
function PromiseHandle(value, handler, deferred) {
try {
+ %DebugPromiseHandlePrologue(
+ function() {
+ var queue = GET_PRIVATE(deferred.promise, promiseOnReject);
+ return (queue && queue.length == 0) ? deferred.promise : UNDEFINED;
+ });
var result = handler(value);
if (result === deferred.promise)
throw MakeTypeError('promise_cyclic', [result]);
@@ -190,9 +172,15 @@ function PromiseHandle(value, handler, deferred) {
%_CallFunction(result, deferred.resolve, deferred.reject, PromiseChain);
else
deferred.resolve(result);
- } catch(e) {
- // TODO(rossberg): perhaps log uncaught exceptions below.
- try { deferred.reject(e) } catch(e) {}
+ } catch (exception) {
+ try {
+ %DebugPromiseHandlePrologue(function() { return deferred.promise });
+ deferred.reject(exception);
+ } catch (e) { } finally {
+ %DebugPromiseHandleEpilogue();
+ }
+ } finally {
+ %DebugPromiseHandleEpilogue();
}
}
@@ -200,10 +188,8 @@ function PromiseHandle(value, handler, deferred) {
// Multi-unwrapped chaining with thenable coercion.
function PromiseThen(onResolve, onReject) {
- onResolve =
- IS_NULL_OR_UNDEFINED(onResolve) ? PromiseIdResolveHandler : onResolve;
- onReject =
- IS_NULL_OR_UNDEFINED(onReject) ? PromiseIdRejectHandler : onReject;
+ onResolve = IS_SPEC_FUNCTION(onResolve) ? onResolve : PromiseIdResolveHandler;
+ onReject = IS_SPEC_FUNCTION(onReject) ? onReject : PromiseIdRejectHandler;
var that = this;
var constructor = this.constructor;
return %_CallFunction(
@@ -324,3 +310,12 @@ function SetUpPromise() {
}
SetUpPromise();
+
+// Functions to expose promise details to the debugger.
+function GetPromiseStatus(promise) {
+ return GET_PRIVATE(promise, promiseStatus);
+}
+
+function GetPromiseValue(promise) {
+ return GET_PRIVATE(promise, promiseValue);
+}
diff --git a/deps/v8/src/property-details-inl.h b/deps/v8/src/property-details-inl.h
index 98eb1cf58e..353f8f5875 100644
--- a/deps/v8/src/property-details-inl.h
+++ b/deps/v8/src/property-details-inl.h
@@ -1,36 +1,13 @@
// Copyright 2014 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PROPERTY_DETAILS_INL_H_
#define V8_PROPERTY_DETAILS_INL_H_
+#include "conversions.h"
#include "objects.h"
#include "property-details.h"
-#include "v8conversions.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/src/property-details.h b/deps/v8/src/property-details.h
index 01050dbd4f..cb33f9c9a7 100644
--- a/deps/v8/src/property-details.h
+++ b/deps/v8/src/property-details.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PROPERTY_DETAILS_H_
#define V8_PROPERTY_DETAILS_H_
@@ -77,9 +54,8 @@ enum PropertyType {
// Only in lookup results, not in descriptors.
HANDLER = 4,
INTERCEPTOR = 5,
- TRANSITION = 6,
// Only used as a marker in LookupResult.
- NONEXISTENT = 7
+ NONEXISTENT = 6
};
diff --git a/deps/v8/src/property.cc b/deps/v8/src/property.cc
index 2f72eec48e..e7d0c4e2f4 100644
--- a/deps/v8/src/property.cc
+++ b/deps/v8/src/property.cc
@@ -1,36 +1,14 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
-#include "v8.h"
+#include "property.h"
+
+#include "handles-inl.h"
namespace v8 {
namespace internal {
-
void LookupResult::Iterate(ObjectVisitor* visitor) {
LookupResult* current = this; // Could be NULL.
while (current != NULL) {
@@ -51,6 +29,11 @@ void LookupResult::Print(FILE* out) {
PrintF(out, "LookupResult:\n");
PrintF(out, " -cacheable = %s\n", IsCacheable() ? "true" : "false");
PrintF(out, " -attributes = %x\n", GetAttributes());
+ if (IsTransition()) {
+ PrintF(out, " -transition target:\n");
+ GetTransitionTarget()->Print(out);
+ PrintF(out, "\n");
+ }
switch (type()) {
case NORMAL:
PrintF(out, " -type = normal\n");
@@ -64,8 +47,9 @@ void LookupResult::Print(FILE* out) {
break;
case FIELD:
PrintF(out, " -type = field\n");
- PrintF(out, " -index = %d", GetFieldIndex().field_index());
- PrintF(out, "\n");
+ PrintF(out, " -index = %d\n", GetFieldIndex().field_index());
+ PrintF(out, " -field type:\n");
+ GetFieldType()->TypePrint(out);
break;
case CALLBACKS:
PrintF(out, " -type = call backs\n");
@@ -78,29 +62,6 @@ void LookupResult::Print(FILE* out) {
case INTERCEPTOR:
PrintF(out, " -type = lookup interceptor\n");
break;
- case TRANSITION:
- switch (GetTransitionDetails().type()) {
- case FIELD:
- PrintF(out, " -type = map transition\n");
- PrintF(out, " -map:\n");
- GetTransitionTarget()->Print(out);
- PrintF(out, "\n");
- return;
- case CONSTANT:
- PrintF(out, " -type = constant property transition\n");
- PrintF(out, " -map:\n");
- GetTransitionTarget()->Print(out);
- PrintF(out, "\n");
- return;
- case CALLBACKS:
- PrintF(out, " -type = callbacks transition\n");
- PrintF(out, " -callback object:\n");
- GetCallbackObject()->Print(out);
- return;
- default:
- UNREACHABLE();
- return;
- }
case NONEXISTENT:
UNREACHABLE();
break;
@@ -114,9 +75,6 @@ void Descriptor::Print(FILE* out) {
PrintF(out, " @ ");
GetValue()->ShortPrint(out);
}
-
-
#endif
-
} } // namespace v8::internal
diff --git a/deps/v8/src/property.h b/deps/v8/src/property.h
index baa5a0f993..c7a4e6a637 100644
--- a/deps/v8/src/property.h
+++ b/deps/v8/src/property.h
@@ -1,60 +1,33 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PROPERTY_H_
#define V8_PROPERTY_H_
-#include "allocation.h"
-#include "transitions.h"
+#include "isolate.h"
+#include "factory.h"
+#include "types.h"
namespace v8 {
namespace internal {
-
// Abstraction for elements in instance-descriptor arrays.
//
// Each descriptor has a key, property attributes, property type,
// property index (in the actual instance-descriptor array) and
// optionally a piece of data.
-//
-
class Descriptor BASE_EMBEDDED {
public:
- MUST_USE_RESULT MaybeObject* KeyToUniqueName() {
+ void KeyToUniqueName() {
if (!key_->IsUniqueName()) {
- MaybeObject* maybe_result =
- key_->GetIsolate()->heap()->InternalizeString(String::cast(key_));
- if (!maybe_result->To(&key_)) return maybe_result;
+ key_ = key_->GetIsolate()->factory()->InternalizeString(
+ Handle<String>::cast(key_));
}
- return key_;
}
- Name* GetKey() { return key_; }
- Object* GetValue() { return value_; }
+ Handle<Name> GetKey() { return key_; }
+ Handle<Object> GetValue() { return value_; }
PropertyDetails GetDetails() { return details_; }
#ifdef OBJECT_PRINT
@@ -64,26 +37,26 @@ class Descriptor BASE_EMBEDDED {
void SetSortedKeyIndex(int index) { details_ = details_.set_pointer(index); }
private:
- Name* key_;
- Object* value_;
+ Handle<Name> key_;
+ Handle<Object> value_;
PropertyDetails details_;
protected:
Descriptor() : details_(Smi::FromInt(0)) {}
- void Init(Name* key, Object* value, PropertyDetails details) {
+ void Init(Handle<Name> key, Handle<Object> value, PropertyDetails details) {
key_ = key;
value_ = value;
details_ = details;
}
- Descriptor(Name* key, Object* value, PropertyDetails details)
+ Descriptor(Handle<Name> key, Handle<Object> value, PropertyDetails details)
: key_(key),
value_(value),
details_(details) { }
- Descriptor(Name* key,
- Object* value,
+ Descriptor(Handle<Name> key,
+ Handle<Object> value,
PropertyAttributes attributes,
PropertyType type,
Representation representation,
@@ -93,34 +66,42 @@ class Descriptor BASE_EMBEDDED {
details_(attributes, type, representation, field_index) { }
friend class DescriptorArray;
+ friend class Map;
};
-class FieldDescriptor: public Descriptor {
+class FieldDescriptor V8_FINAL : public Descriptor {
public:
- FieldDescriptor(Name* key,
+ FieldDescriptor(Handle<Name> key,
int field_index,
PropertyAttributes attributes,
Representation representation)
- : Descriptor(key, Smi::FromInt(0), attributes,
+ : Descriptor(key, HeapType::Any(key->GetIsolate()), attributes,
FIELD, representation, field_index) {}
+ FieldDescriptor(Handle<Name> key,
+ int field_index,
+ Handle<HeapType> field_type,
+ PropertyAttributes attributes,
+ Representation representation)
+ : Descriptor(key, field_type, attributes, FIELD,
+ representation, field_index) { }
};
-class ConstantDescriptor: public Descriptor {
+class ConstantDescriptor V8_FINAL : public Descriptor {
public:
- ConstantDescriptor(Name* key,
- Object* value,
+ ConstantDescriptor(Handle<Name> key,
+ Handle<Object> value,
PropertyAttributes attributes)
: Descriptor(key, value, attributes, CONSTANT,
value->OptimalRepresentation()) {}
};
-class CallbacksDescriptor: public Descriptor {
+class CallbacksDescriptor V8_FINAL : public Descriptor {
public:
- CallbacksDescriptor(Name* key,
- Object* foreign,
+ CallbacksDescriptor(Handle<Name> key,
+ Handle<Object> foreign,
PropertyAttributes attributes)
: Descriptor(key, foreign, attributes, CALLBACKS,
Representation::Tagged()) {}
@@ -129,7 +110,7 @@ class CallbacksDescriptor: public Descriptor {
// Holds a property index value distinguishing if it is a field index or an
// index inside the object header.
-class PropertyIndex {
+class PropertyIndex V8_FINAL {
public:
static PropertyIndex NewFieldIndex(int index) {
return PropertyIndex(index, false);
@@ -177,7 +158,7 @@ class PropertyIndex {
};
-class LookupResult BASE_EMBEDDED {
+class LookupResult V8_FINAL BASE_EMBEDDED {
public:
explicit LookupResult(Isolate* isolate)
: isolate_(isolate),
@@ -205,18 +186,34 @@ class LookupResult BASE_EMBEDDED {
number_ = number;
}
- bool CanHoldValue(Handle<Object> value) {
- if (IsNormal()) return true;
- ASSERT(!IsTransition());
- return value->FitsRepresentation(details_.representation());
+ bool CanHoldValue(Handle<Object> value) const {
+ switch (type()) {
+ case NORMAL:
+ return true;
+ case FIELD:
+ return value->FitsRepresentation(representation()) &&
+ GetFieldType()->NowContains(value);
+ case CONSTANT:
+ ASSERT(GetConstant() != *value ||
+ value->FitsRepresentation(representation()));
+ return GetConstant() == *value;
+ case CALLBACKS:
+ case HANDLER:
+ case INTERCEPTOR:
+ return true;
+ case NONEXISTENT:
+ UNREACHABLE();
+ }
+ UNREACHABLE();
+ return true;
}
void TransitionResult(JSObject* holder, Map* target) {
lookup_type_ = TRANSITION_TYPE;
- details_ = PropertyDetails(NONE, TRANSITION, Representation::None());
+ number_ = target->LastAdded();
+ details_ = target->instance_descriptors()->GetDetails(number_);
holder_ = holder;
transition_ = target;
- number_ = 0xAAAA;
}
void DictionaryResult(JSObject* holder, int entry) {
@@ -266,20 +263,17 @@ class LookupResult BASE_EMBEDDED {
Representation representation() const {
ASSERT(IsFound());
- ASSERT(!IsTransition());
ASSERT(details_.type() != NONEXISTENT);
return details_.representation();
}
PropertyAttributes GetAttributes() const {
- ASSERT(!IsTransition());
ASSERT(IsFound());
ASSERT(details_.type() != NONEXISTENT);
return details_.attributes();
}
PropertyDetails GetPropertyDetails() const {
- ASSERT(!IsTransition());
return details_;
}
@@ -291,38 +285,40 @@ class LookupResult BASE_EMBEDDED {
// Property callbacks does not include transitions to callbacks.
bool IsPropertyCallbacks() const {
ASSERT(!(details_.type() == CALLBACKS && !IsFound()));
- return details_.type() == CALLBACKS;
+ return !IsTransition() && details_.type() == CALLBACKS;
}
bool IsReadOnly() const {
ASSERT(IsFound());
- ASSERT(!IsTransition());
ASSERT(details_.type() != NONEXISTENT);
return details_.IsReadOnly();
}
bool IsField() const {
ASSERT(!(details_.type() == FIELD && !IsFound()));
- return details_.type() == FIELD;
+ return IsDescriptorOrDictionary() && type() == FIELD;
}
bool IsNormal() const {
ASSERT(!(details_.type() == NORMAL && !IsFound()));
- return details_.type() == NORMAL;
+ return IsDescriptorOrDictionary() && type() == NORMAL;
}
bool IsConstant() const {
ASSERT(!(details_.type() == CONSTANT && !IsFound()));
- return details_.type() == CONSTANT;
+ return IsDescriptorOrDictionary() && type() == CONSTANT;
}
bool IsConstantFunction() const {
- return IsConstant() && GetValue()->IsJSFunction();
+ return IsConstant() && GetConstant()->IsJSFunction();
}
bool IsDontDelete() const { return details_.IsDontDelete(); }
bool IsDontEnum() const { return details_.IsDontEnum(); }
bool IsFound() const { return lookup_type_ != NOT_FOUND; }
+ bool IsDescriptorOrDictionary() const {
+ return lookup_type_ == DESCRIPTOR_TYPE || lookup_type_ == DICTIONARY_TYPE;
+ }
bool IsTransition() const { return lookup_type_ == TRANSITION_TYPE; }
bool IsHandler() const { return lookup_type_ == HANDLER_TYPE; }
bool IsInterceptor() const { return lookup_type_ == INTERCEPTOR_TYPE; }
@@ -333,20 +329,31 @@ class LookupResult BASE_EMBEDDED {
}
bool IsDataProperty() const {
- switch (type()) {
- case FIELD:
- case NORMAL:
- case CONSTANT:
- return true;
- case CALLBACKS: {
- Object* callback = GetCallbackObject();
- return callback->IsAccessorInfo() || callback->IsForeign();
- }
- case HANDLER:
- case INTERCEPTOR:
- case TRANSITION:
- case NONEXISTENT:
+ switch (lookup_type_) {
+ case NOT_FOUND:
+ case TRANSITION_TYPE:
+ case HANDLER_TYPE:
+ case INTERCEPTOR_TYPE:
return false;
+
+ case DESCRIPTOR_TYPE:
+ case DICTIONARY_TYPE:
+ switch (type()) {
+ case FIELD:
+ case NORMAL:
+ case CONSTANT:
+ return true;
+ case CALLBACKS: {
+ Object* callback = GetCallbackObject();
+ ASSERT(!callback->IsForeign());
+ return callback->IsAccessorInfo();
+ }
+ case HANDLER:
+ case INTERCEPTOR:
+ case NONEXISTENT:
+ UNREACHABLE();
+ return false;
+ }
}
UNREACHABLE();
return false;
@@ -356,45 +363,52 @@ class LookupResult BASE_EMBEDDED {
void DisallowCaching() { cacheable_ = false; }
Object* GetLazyValue() const {
- switch (type()) {
- case FIELD:
- return holder()->RawFastPropertyAt(GetFieldIndex().field_index());
- case NORMAL: {
- Object* value;
- value = holder()->property_dictionary()->ValueAt(GetDictionaryEntry());
- if (holder()->IsGlobalObject()) {
- value = PropertyCell::cast(value)->value();
- }
- return value;
- }
- case CONSTANT:
- return GetConstant();
- case CALLBACKS:
- case HANDLER:
- case INTERCEPTOR:
- case TRANSITION:
- case NONEXISTENT:
+ switch (lookup_type_) {
+ case NOT_FOUND:
+ case TRANSITION_TYPE:
+ case HANDLER_TYPE:
+ case INTERCEPTOR_TYPE:
return isolate()->heap()->the_hole_value();
+
+ case DESCRIPTOR_TYPE:
+ case DICTIONARY_TYPE:
+ switch (type()) {
+ case FIELD:
+ return holder()->RawFastPropertyAt(GetFieldIndex().field_index());
+ case NORMAL: {
+ Object* value = holder()->property_dictionary()->ValueAt(
+ GetDictionaryEntry());
+ if (holder()->IsGlobalObject()) {
+ value = PropertyCell::cast(value)->value();
+ }
+ return value;
+ }
+ case CONSTANT:
+ return GetConstant();
+ case CALLBACKS:
+ return isolate()->heap()->the_hole_value();
+ case HANDLER:
+ case INTERCEPTOR:
+ case NONEXISTENT:
+ UNREACHABLE();
+ return NULL;
+ }
}
UNREACHABLE();
return NULL;
}
Map* GetTransitionTarget() const {
- return transition_;
- }
-
- PropertyDetails GetTransitionDetails() const {
ASSERT(IsTransition());
- return transition_->GetLastDescriptorDetails();
+ return transition_;
}
bool IsTransitionToField() const {
- return IsTransition() && GetTransitionDetails().type() == FIELD;
+ return IsTransition() && details_.type() == FIELD;
}
bool IsTransitionToConstant() const {
- return IsTransition() && GetTransitionDetails().type() == CONSTANT;
+ return IsTransition() && details_.type() == CONSTANT;
}
int GetDescriptorIndex() const {
@@ -403,7 +417,8 @@ class LookupResult BASE_EMBEDDED {
}
PropertyIndex GetFieldIndex() const {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
+ lookup_type_ == TRANSITION_TYPE);
return PropertyIndex::NewFieldIndex(GetFieldIndexFromMap(holder()->map()));
}
@@ -436,7 +451,8 @@ class LookupResult BASE_EMBEDDED {
}
Object* GetCallbackObject() const {
- ASSERT(type() == CALLBACKS && !IsTransition());
+ ASSERT(!IsTransition());
+ ASSERT(type() == CALLBACKS);
return GetValue();
}
@@ -447,6 +463,8 @@ class LookupResult BASE_EMBEDDED {
Object* GetValue() const {
if (lookup_type_ == DESCRIPTOR_TYPE) {
return GetValueFromMap(holder()->map());
+ } else if (lookup_type_ == TRANSITION_TYPE) {
+ return GetValueFromMap(transition_);
}
// In the dictionary case, the data is held in the value field.
ASSERT(lookup_type_ == DICTIONARY_TYPE);
@@ -454,17 +472,46 @@ class LookupResult BASE_EMBEDDED {
}
Object* GetValueFromMap(Map* map) const {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
+ lookup_type_ == TRANSITION_TYPE);
ASSERT(number_ < map->NumberOfOwnDescriptors());
return map->instance_descriptors()->GetValue(number_);
}
int GetFieldIndexFromMap(Map* map) const {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
+ lookup_type_ == TRANSITION_TYPE);
ASSERT(number_ < map->NumberOfOwnDescriptors());
return map->instance_descriptors()->GetFieldIndex(number_);
}
+ HeapType* GetFieldType() const {
+ ASSERT(type() == FIELD);
+ if (lookup_type_ == DESCRIPTOR_TYPE) {
+ return GetFieldTypeFromMap(holder()->map());
+ }
+ ASSERT(lookup_type_ == TRANSITION_TYPE);
+ return GetFieldTypeFromMap(transition_);
+ }
+
+ HeapType* GetFieldTypeFromMap(Map* map) const {
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
+ lookup_type_ == TRANSITION_TYPE);
+ ASSERT(number_ < map->NumberOfOwnDescriptors());
+ return map->instance_descriptors()->GetFieldType(number_);
+ }
+
+ Map* GetFieldOwner() const {
+ return GetFieldOwnerFromMap(holder()->map());
+ }
+
+ Map* GetFieldOwnerFromMap(Map* map) const {
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
+ lookup_type_ == TRANSITION_TYPE);
+ ASSERT(number_ < map->NumberOfOwnDescriptors());
+ return map->FindFieldOwner(number_);
+ }
+
void Iterate(ObjectVisitor* visitor);
private:
@@ -488,7 +535,6 @@ class LookupResult BASE_EMBEDDED {
PropertyDetails details_;
};
-
} } // namespace v8::internal
#endif // V8_PROPERTY_H_
diff --git a/deps/v8/src/proxy.js b/deps/v8/src/proxy.js
index 06be087c71..99f9dab9f3 100644
--- a/deps/v8/src/proxy.js
+++ b/deps/v8/src/proxy.js
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
"use strict";
diff --git a/deps/v8/src/qnx-math.h b/deps/v8/src/qnx-math.h
index bd8474599b..8cf65d208c 100644
--- a/deps/v8/src/qnx-math.h
+++ b/deps/v8/src/qnx-math.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_QNX_MATH_H_
#define V8_QNX_MATH_H_
diff --git a/deps/v8/src/regexp-macro-assembler-irregexp-inl.h b/deps/v8/src/regexp-macro-assembler-irregexp-inl.h
index a767ec0089..8fe6a42775 100644
--- a/deps/v8/src/regexp-macro-assembler-irregexp-inl.h
+++ b/deps/v8/src/regexp-macro-assembler-irregexp-inl.h
@@ -1,29 +1,6 @@
// Copyright 2008-2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// A light-weight assembler for the Irregexp byte code.
diff --git a/deps/v8/src/regexp-macro-assembler-irregexp.cc b/deps/v8/src/regexp-macro-assembler-irregexp.cc
index 3b9a2f6603..368fb3006c 100644
--- a/deps/v8/src/regexp-macro-assembler-irregexp.cc
+++ b/deps/v8/src/regexp-macro-assembler-irregexp.cc
@@ -1,29 +1,6 @@
// Copyright 2008-2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
#include "ast.h"
diff --git a/deps/v8/src/regexp-macro-assembler-irregexp.h b/deps/v8/src/regexp-macro-assembler-irregexp.h
index f8a412d4f8..54afe92e13 100644
--- a/deps/v8/src/regexp-macro-assembler-irregexp.h
+++ b/deps/v8/src/regexp-macro-assembler-irregexp.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_REGEXP_MACRO_ASSEMBLER_IRREGEXP_H_
#define V8_REGEXP_MACRO_ASSEMBLER_IRREGEXP_H_
diff --git a/deps/v8/src/regexp-macro-assembler-tracer.cc b/deps/v8/src/regexp-macro-assembler-tracer.cc
index 75e4392478..c307eaf611 100644
--- a/deps/v8/src/regexp-macro-assembler-tracer.cc
+++ b/deps/v8/src/regexp-macro-assembler-tracer.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
#include "ast.h"
diff --git a/deps/v8/src/regexp-macro-assembler-tracer.h b/deps/v8/src/regexp-macro-assembler-tracer.h
index 852fb80417..ac76cfdb06 100644
--- a/deps/v8/src/regexp-macro-assembler-tracer.h
+++ b/deps/v8/src/regexp-macro-assembler-tracer.h
@@ -1,29 +1,6 @@
// Copyright 2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_REGEXP_MACRO_ASSEMBLER_TRACER_H_
#define V8_REGEXP_MACRO_ASSEMBLER_TRACER_H_
diff --git a/deps/v8/src/regexp-macro-assembler.cc b/deps/v8/src/regexp-macro-assembler.cc
index 7d027f880f..a522f97c6c 100644
--- a/deps/v8/src/regexp-macro-assembler.cc
+++ b/deps/v8/src/regexp-macro-assembler.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
#include "ast.h"
diff --git a/deps/v8/src/regexp-macro-assembler.h b/deps/v8/src/regexp-macro-assembler.h
index fc3100867b..8d9129504d 100644
--- a/deps/v8/src/regexp-macro-assembler.h
+++ b/deps/v8/src/regexp-macro-assembler.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_REGEXP_MACRO_ASSEMBLER_H_
#define V8_REGEXP_MACRO_ASSEMBLER_H_
diff --git a/deps/v8/src/regexp-stack.cc b/deps/v8/src/regexp-stack.cc
index f3af490f1e..5e250dd85e 100644
--- a/deps/v8/src/regexp-stack.cc
+++ b/deps/v8/src/regexp-stack.cc
@@ -1,29 +1,6 @@
// Copyright 2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
#include "regexp-stack.h"
diff --git a/deps/v8/src/regexp-stack.h b/deps/v8/src/regexp-stack.h
index 5684239f9f..745782d73b 100644
--- a/deps/v8/src/regexp-stack.h
+++ b/deps/v8/src/regexp-stack.h
@@ -1,29 +1,6 @@
// Copyright 2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_REGEXP_STACK_H_
#define V8_REGEXP_STACK_H_
diff --git a/deps/v8/src/regexp.js b/deps/v8/src/regexp.js
index 22b08775b3..6a0e2b5d92 100644
--- a/deps/v8/src/regexp.js
+++ b/deps/v8/src/regexp.js
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file relies on the fact that the following declaration has been made
// in runtime.js:
@@ -185,7 +162,6 @@ function RegExpExec(string) {
i = 0;
}
- %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, string, lastIndex]);
// matchIndices is either null or the lastMatchInfo array.
var matchIndices = %_RegExpExec(this, string, i, lastMatchInfo);
@@ -229,7 +205,6 @@ function RegExpTest(string) {
this.lastIndex = 0;
return false;
}
- %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, string, lastIndex]);
// matchIndices is either null or the lastMatchInfo array.
var matchIndices = %_RegExpExec(this, string, i, lastMatchInfo);
if (IS_NULL(matchIndices)) {
@@ -250,7 +225,6 @@ function RegExpTest(string) {
%_StringCharCodeAt(regexp.source, 2) != 63) { // '?'
regexp = TrimRegExp(regexp);
}
- %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [regexp, string, lastIndex]);
// matchIndices is either null or the lastMatchInfo array.
var matchIndices = %_RegExpExec(regexp, string, 0, lastMatchInfo);
if (IS_NULL(matchIndices)) {
diff --git a/deps/v8/src/rewriter.cc b/deps/v8/src/rewriter.cc
index 2b68ed1c90..27f03dc7a4 100644
--- a/deps/v8/src/rewriter.cc
+++ b/deps/v8/src/rewriter.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/rewriter.h b/deps/v8/src/rewriter.h
index 59914d97f9..0423802bad 100644
--- a/deps/v8/src/rewriter.h
+++ b/deps/v8/src/rewriter.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_REWRITER_H_
#define V8_REWRITER_H_
diff --git a/deps/v8/src/runtime-profiler.cc b/deps/v8/src/runtime-profiler.cc
index 5784e4d5aa..69229871ea 100644
--- a/deps/v8/src/runtime-profiler.cc
+++ b/deps/v8/src/runtime-profiler.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -185,6 +162,16 @@ void RuntimeProfiler::OptimizeNow() {
SharedFunctionInfo* shared = function->shared();
Code* shared_code = shared->code();
+ List<JSFunction*> functions(4);
+ frame->GetFunctions(&functions);
+ for (int i = functions.length(); --i >= 0; ) {
+ SharedFunctionInfo* shared_function_info = functions[i]->shared();
+ int ticks = shared_function_info->profiler_ticks();
+ if (ticks < Smi::kMaxValue) {
+ shared_function_info->set_profiler_ticks(ticks + 1);
+ }
+ }
+
if (shared_code->kind() != Code::FUNCTION) continue;
if (function->IsInOptimizationQueue()) continue;
diff --git a/deps/v8/src/runtime-profiler.h b/deps/v8/src/runtime-profiler.h
index efd9b50eb5..450910ca82 100644
--- a/deps/v8/src/runtime-profiler.h
+++ b/deps/v8/src/runtime-profiler.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_RUNTIME_PROFILER_H_
#define V8_RUNTIME_PROFILER_H_
diff --git a/deps/v8/src/runtime.cc b/deps/v8/src/runtime.cc
index 5142fd33df..b82d377f71 100644
--- a/deps/v8/src/runtime.cc
+++ b/deps/v8/src/runtime.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <stdlib.h>
#include <limits>
@@ -38,6 +15,7 @@
#include "codegen.h"
#include "compilation-cache.h"
#include "compiler.h"
+#include "conversions.h"
#include "cpu.h"
#include "cpu-profiler.h"
#include "dateparser-inl.h"
@@ -63,7 +41,6 @@
#include "string-search.h"
#include "stub-cache.h"
#include "uri.h"
-#include "v8conversions.h"
#include "v8threads.h"
#include "vm-state-inl.h"
@@ -105,6 +82,12 @@ namespace internal {
#define RUNTIME_ASSERT(value) \
if (!(value)) return isolate->ThrowIllegalOperation();
+#define RUNTIME_ASSERT_HANDLIFIED(value, T) \
+ if (!(value)) { \
+ isolate->ThrowIllegalOperation(); \
+ return MaybeHandle<T>(); \
+ }
+
// Cast the given object to a value of the specified type and store
// it in a variable with the given name. If the object is not of the
// expected type call IllegalOperation and return.
@@ -116,6 +99,10 @@ namespace internal {
RUNTIME_ASSERT(args[index]->Is##Type()); \
Handle<Type> name = args.at<Type>(index);
+#define CONVERT_NUMBER_ARG_HANDLE_CHECKED(name, index) \
+ RUNTIME_ASSERT(args[index]->IsNumber()); \
+ Handle<Object> name = args.at<Object>(index);
+
// Cast the given object to a boolean and store it in a variable with
// the given name. If the object is not a boolean call IllegalOperation
// and return.
@@ -209,19 +196,17 @@ static Handle<Map> ComputeObjectLiteralMap(
return isolate->factory()->ObjectLiteralMapFromCache(context, keys);
}
*is_result_from_cache = false;
- return isolate->factory()->CopyMap(
- Handle<Map>(context->object_function()->initial_map()),
- number_of_properties);
+ return Map::Create(handle(context->object_function()), number_of_properties);
}
-static Handle<Object> CreateLiteralBoilerplate(
+MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
Isolate* isolate,
Handle<FixedArray> literals,
Handle<FixedArray> constant_properties);
-static Handle<Object> CreateObjectLiteralBoilerplate(
+MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
Isolate* isolate,
Handle<FixedArray> literals,
Handle<FixedArray> constant_properties,
@@ -276,27 +261,29 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
// The value contains the constant_properties of a
// simple object or array literal.
Handle<FixedArray> array = Handle<FixedArray>::cast(value);
- value = CreateLiteralBoilerplate(isolate, literals, array);
- if (value.is_null()) return value;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, value,
+ CreateLiteralBoilerplate(isolate, literals, array),
+ Object);
}
- Handle<Object> result;
+ MaybeHandle<Object> maybe_result;
uint32_t element_index = 0;
StoreMode mode = value->IsJSObject() ? FORCE_FIELD : ALLOW_AS_CONSTANT;
if (key->IsInternalizedString()) {
if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
// Array index as string (uint32).
- result = JSObject::SetOwnElement(
+ maybe_result = JSObject::SetOwnElement(
boilerplate, element_index, value, SLOPPY);
} else {
Handle<String> name(String::cast(*key));
ASSERT(!name->AsArrayIndex(&element_index));
- result = JSObject::SetLocalPropertyIgnoreAttributes(
+ maybe_result = JSObject::SetLocalPropertyIgnoreAttributes(
boilerplate, name, value, NONE,
Object::OPTIMAL_REPRESENTATION, mode);
}
} else if (key->ToArrayIndex(&element_index)) {
// Array index (uint32).
- result = JSObject::SetOwnElement(
+ maybe_result = JSObject::SetOwnElement(
boilerplate, element_index, value, SLOPPY);
} else {
// Non-uint32 number.
@@ -305,9 +292,8 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
char arr[100];
Vector<char> buffer(arr, ARRAY_SIZE(arr));
const char* str = DoubleToCString(num, buffer);
- Handle<String> name =
- isolate->factory()->NewStringFromAscii(CStrVector(str));
- result = JSObject::SetLocalPropertyIgnoreAttributes(
+ Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str);
+ maybe_result = JSObject::SetLocalPropertyIgnoreAttributes(
boilerplate, name, value, NONE,
Object::OPTIMAL_REPRESENTATION, mode);
}
@@ -315,7 +301,7 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
// exception, the exception is converted to an empty handle in
// the handle based operations. In that case, we need to
// convert back to an exception.
- if (result.is_null()) return result;
+ RETURN_ON_EXCEPTION(isolate, maybe_result, Object);
}
// Transform to fast properties if necessary. For object literals with
@@ -331,25 +317,30 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
}
-MaybeObject* TransitionElements(Handle<Object> object,
- ElementsKind to_kind,
- Isolate* isolate) {
+MUST_USE_RESULT static MaybeHandle<Object> TransitionElements(
+ Handle<Object> object,
+ ElementsKind to_kind,
+ Isolate* isolate) {
HandleScope scope(isolate);
- if (!object->IsJSObject()) return isolate->ThrowIllegalOperation();
+ if (!object->IsJSObject()) {
+ isolate->ThrowIllegalOperation();
+ return MaybeHandle<Object>();
+ }
ElementsKind from_kind =
Handle<JSObject>::cast(object)->map()->elements_kind();
if (Map::IsValidElementsTransition(from_kind, to_kind)) {
JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
- return *object;
+ return object;
}
- return isolate->ThrowIllegalOperation();
+ isolate->ThrowIllegalOperation();
+ return MaybeHandle<Object>();
}
static const int kSmiLiteralMinimumLength = 1024;
-Handle<Object> Runtime::CreateArrayLiteralBoilerplate(
+MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
Isolate* isolate,
Handle<FixedArray> literals,
Handle<FixedArray> elements) {
@@ -368,14 +359,14 @@ Handle<Object> Runtime::CreateArrayLiteralBoilerplate(
Handle<FixedArrayBase> constant_elements_values(
FixedArrayBase::cast(elements->get(1)));
- ASSERT(IsFastElementsKind(constant_elements_kind));
- Context* native_context = isolate->context()->native_context();
- Object* maybe_maps_array = native_context->js_array_maps();
- ASSERT(!maybe_maps_array->IsUndefined());
- Object* maybe_map = FixedArray::cast(maybe_maps_array)->get(
- constant_elements_kind);
- ASSERT(maybe_map->IsMap());
- object->set_map(Map::cast(maybe_map));
+ { DisallowHeapAllocation no_gc;
+ ASSERT(IsFastElementsKind(constant_elements_kind));
+ Context* native_context = isolate->context()->native_context();
+ Object* maps_array = native_context->js_array_maps();
+ ASSERT(!maps_array->IsUndefined());
+ Object* map = FixedArray::cast(maps_array)->get(constant_elements_kind);
+ object->set_map(Map::cast(map));
+ }
Handle<FixedArrayBase> copied_elements_values;
if (IsFastDoubleElementsKind(constant_elements_kind)) {
@@ -403,14 +394,15 @@ Handle<Object> Runtime::CreateArrayLiteralBoilerplate(
isolate->factory()->CopyFixedArray(fixed_array_values);
copied_elements_values = fixed_array_values_copy;
for (int i = 0; i < fixed_array_values->length(); i++) {
- Object* current = fixed_array_values->get(i);
- if (current->IsFixedArray()) {
+ if (fixed_array_values->get(i)->IsFixedArray()) {
// The value contains the constant_properties of a
// simple object or array literal.
Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
- Handle<Object> result =
- CreateLiteralBoilerplate(isolate, literals, fa);
- if (result.is_null()) return result;
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ CreateLiteralBoilerplate(isolate, literals, fa),
+ Object);
fixed_array_values_copy->set(i, *result);
}
}
@@ -426,20 +418,19 @@ Handle<Object> Runtime::CreateArrayLiteralBoilerplate(
ElementsKind elements_kind = object->GetElementsKind();
if (!IsFastObjectElementsKind(elements_kind)) {
if (IsFastHoleyElementsKind(elements_kind)) {
- CHECK(!TransitionElements(object, FAST_HOLEY_ELEMENTS,
- isolate)->IsFailure());
+ TransitionElements(object, FAST_HOLEY_ELEMENTS, isolate).Check();
} else {
- CHECK(!TransitionElements(object, FAST_ELEMENTS, isolate)->IsFailure());
+ TransitionElements(object, FAST_ELEMENTS, isolate).Check();
}
}
}
- object->ValidateElements();
+ JSObject::ValidateElements(object);
return object;
}
-static Handle<Object> CreateLiteralBoilerplate(
+MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
Isolate* isolate,
Handle<FixedArray> literals,
Handle<FixedArray> array) {
@@ -463,12 +454,12 @@ static Handle<Object> CreateLiteralBoilerplate(
isolate, literals, elements);
default:
UNREACHABLE();
- return Handle<Object>::null();
+ return MaybeHandle<Object>();
}
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_CreateObjectLiteral) {
+RUNTIME_FUNCTION(RuntimeHidden_CreateObjectLiteral) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
@@ -478,24 +469,29 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_CreateObjectLiteral) {
bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
+ RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length());
+
// Check if boilerplate exists. If not, create it first.
Handle<Object> literal_site(literals->get(literals_index), isolate);
Handle<AllocationSite> site;
Handle<JSObject> boilerplate;
if (*literal_site == isolate->heap()->undefined_value()) {
- Handle<Object> raw_boilerplate = CreateObjectLiteralBoilerplate(
- isolate,
- literals,
- constant_properties,
- should_have_fast_elements,
- has_function_literal);
- RETURN_IF_EMPTY_HANDLE(isolate, raw_boilerplate);
+ Handle<Object> raw_boilerplate;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, raw_boilerplate,
+ CreateObjectLiteralBoilerplate(
+ isolate,
+ literals,
+ constant_properties,
+ should_have_fast_elements,
+ has_function_literal));
boilerplate = Handle<JSObject>::cast(raw_boilerplate);
AllocationSiteCreationContext creation_context(isolate);
site = creation_context.EnterNewScope();
- RETURN_IF_EMPTY_HANDLE(isolate,
- JSObject::DeepWalk(boilerplate, &creation_context));
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ JSObject::DeepWalk(boilerplate, &creation_context));
creation_context.ExitScope(site, boilerplate);
// Update the functions literal and return the boilerplate.
@@ -508,14 +504,16 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_CreateObjectLiteral) {
AllocationSiteUsageContext usage_context(isolate, site, true);
usage_context.EnterNewScope();
- Handle<Object> copy = JSObject::DeepCopy(boilerplate, &usage_context);
+ MaybeHandle<Object> maybe_copy = JSObject::DeepCopy(
+ boilerplate, &usage_context);
usage_context.ExitScope(site, boilerplate);
- RETURN_IF_EMPTY_HANDLE(isolate, copy);
+ Handle<Object> copy;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, copy, maybe_copy);
return *copy;
}
-static Handle<AllocationSite> GetLiteralAllocationSite(
+MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite(
Isolate* isolate,
Handle<FixedArray> literals,
int literals_index,
@@ -525,9 +523,11 @@ static Handle<AllocationSite> GetLiteralAllocationSite(
Handle<AllocationSite> site;
if (*literal_site == isolate->heap()->undefined_value()) {
ASSERT(*elements != isolate->heap()->empty_fixed_array());
- Handle<Object> boilerplate =
- Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements);
- if (boilerplate.is_null()) return Handle<AllocationSite>::null();
+ Handle<Object> boilerplate;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, boilerplate,
+ Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements),
+ AllocationSite);
AllocationSiteCreationContext creation_context(isolate);
site = creation_context.EnterNewScope();
@@ -546,14 +546,18 @@ static Handle<AllocationSite> GetLiteralAllocationSite(
}
-static MaybeObject* CreateArrayLiteralImpl(Isolate* isolate,
+static MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate,
Handle<FixedArray> literals,
int literals_index,
Handle<FixedArray> elements,
int flags) {
- Handle<AllocationSite> site = GetLiteralAllocationSite(isolate, literals,
- literals_index, elements);
- RETURN_IF_EMPTY_HANDLE(isolate, site);
+ RUNTIME_ASSERT_HANDLIFIED(literals_index >= 0 &&
+ literals_index < literals->length(), JSObject);
+ Handle<AllocationSite> site;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, site,
+ GetLiteralAllocationSite(isolate, literals, literals_index, elements),
+ JSObject);
bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0;
Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
@@ -562,15 +566,14 @@ static MaybeObject* CreateArrayLiteralImpl(Isolate* isolate,
JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0
? JSObject::kNoHints
: JSObject::kObjectIsShallowArray;
- Handle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context,
- hints);
+ MaybeHandle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context,
+ hints);
usage_context.ExitScope(site, boilerplate);
- RETURN_IF_EMPTY_HANDLE(isolate, copy);
- return *copy;
+ return copy;
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_CreateArrayLiteral) {
+RUNTIME_FUNCTION(RuntimeHidden_CreateArrayLiteral) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
@@ -578,76 +581,83 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_CreateArrayLiteral) {
CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
CONVERT_SMI_ARG_CHECKED(flags, 3);
- return CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
- flags);
+ Handle<JSObject> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+ CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
+ flags));
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_CreateArrayLiteralStubBailout) {
+RUNTIME_FUNCTION(RuntimeHidden_CreateArrayLiteralStubBailout) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
CONVERT_SMI_ARG_CHECKED(literals_index, 1);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
- return CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
- ArrayLiteral::kShallowElements);
+ Handle<JSObject> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+ CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
+ ArrayLiteral::kShallowElements));
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateSymbol) {
+RUNTIME_FUNCTION(Runtime_CreateSymbol) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- Handle<Object> name(args[0], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
- Symbol* symbol;
- MaybeObject* maybe = isolate->heap()->AllocateSymbol();
- if (!maybe->To(&symbol)) return maybe;
+ Handle<Symbol> symbol = isolate->factory()->NewSymbol();
if (name->IsString()) symbol->set_name(*name);
- return symbol;
+ return *symbol;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CreatePrivateSymbol) {
+RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- Handle<Object> name(args[0], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
- Symbol* symbol;
- MaybeObject* maybe = isolate->heap()->AllocatePrivateSymbol();
- if (!maybe->To(&symbol)) return maybe;
+ Handle<Symbol> symbol = isolate->factory()->NewPrivateSymbol();
if (name->IsString()) symbol->set_name(*name);
- return symbol;
+ return *symbol;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateGlobalPrivateSymbol) {
+RUNTIME_FUNCTION(Runtime_CreateGlobalPrivateSymbol) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
Handle<JSObject> registry = isolate->GetSymbolRegistry();
Handle<String> part = isolate->factory()->private_intern_string();
- Handle<JSObject> privates =
- Handle<JSObject>::cast(JSObject::GetProperty(registry, part));
- Handle<Object> symbol = JSObject::GetProperty(privates, name);
+ Handle<Object> privates;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, privates, Object::GetPropertyOrElement(registry, part));
+ Handle<Object> symbol;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, symbol, Object::GetPropertyOrElement(privates, name));
if (!symbol->IsSymbol()) {
ASSERT(symbol->IsUndefined());
symbol = isolate->factory()->NewPrivateSymbol();
Handle<Symbol>::cast(symbol)->set_name(*name);
- JSObject::SetProperty(privates, name, symbol, NONE, STRICT);
+ JSObject::SetProperty(Handle<JSObject>::cast(privates),
+ name, symbol, NONE, STRICT).Assert();
}
return *symbol;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NewSymbolWrapper) {
+RUNTIME_FUNCTION(Runtime_NewSymbolWrapper) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(Symbol, symbol, 0);
- return symbol->ToObject(isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Symbol, symbol, 0);
+ return *Object::ToObject(isolate, symbol).ToHandleChecked();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolDescription) {
+RUNTIME_FUNCTION(Runtime_SymbolDescription) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(Symbol, symbol, 0);
@@ -655,14 +665,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolDescription) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolRegistry) {
+RUNTIME_FUNCTION(Runtime_SymbolRegistry) {
HandleScope scope(isolate);
ASSERT(args.length() == 0);
return *isolate->GetSymbolRegistry();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolIsPrivate) {
+RUNTIME_FUNCTION(Runtime_SymbolIsPrivate) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(Symbol, symbol, 0);
@@ -670,49 +680,47 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SymbolIsPrivate) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_CreateJSProxy) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSReceiver, handler, 0);
- Object* prototype = args[1];
- Object* used_prototype =
- prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
- return isolate->heap()->AllocateJSProxy(handler, used_prototype);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
+ if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
+ return *isolate->factory()->NewJSProxy(handler, prototype);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSFunctionProxy) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 4);
- CONVERT_ARG_CHECKED(JSReceiver, handler, 0);
- Object* call_trap = args[1];
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, call_trap, 1);
RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
- CONVERT_ARG_CHECKED(JSFunction, construct_trap, 2);
- Object* prototype = args[3];
- Object* used_prototype =
- prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
- return isolate->heap()->AllocateJSFunctionProxy(
- handler, call_trap, construct_trap, used_prototype);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2);
+ CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3);
+ if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
+ return *isolate->factory()->NewJSFunctionProxy(
+ handler, call_trap, construct_trap, prototype);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) {
+RUNTIME_FUNCTION(Runtime_IsJSProxy) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
- Object* obj = args[0];
+ CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
return isolate->heap()->ToBoolean(obj->IsJSProxy());
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSFunctionProxy) {
+RUNTIME_FUNCTION(Runtime_IsJSFunctionProxy) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
- Object* obj = args[0];
+ CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy());
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) {
+RUNTIME_FUNCTION(Runtime_GetHandler) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
@@ -720,7 +728,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetCallTrap) {
+RUNTIME_FUNCTION(Runtime_GetCallTrap) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
@@ -728,7 +736,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetCallTrap) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructTrap) {
+RUNTIME_FUNCTION(Runtime_GetConstructTrap) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
@@ -736,7 +744,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructTrap) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) {
+RUNTIME_FUNCTION(Runtime_Fix) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
@@ -802,7 +810,7 @@ bool Runtime::SetupArrayBufferAllocatingData(
data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
} else {
data =
- V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
+ V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
}
if (data == NULL) return false;
} else {
@@ -835,41 +843,32 @@ void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) {
+RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, byteLength, 1);
- size_t allocated_length;
- if (byteLength->IsSmi()) {
- allocated_length = Smi::cast(*byteLength)->value();
- } else {
- ASSERT(byteLength->IsHeapNumber());
- double value = HeapNumber::cast(*byteLength)->value();
-
- ASSERT(value >= 0);
-
- if (value > std::numeric_limits<size_t>::max()) {
- return isolate->Throw(
- *isolate->factory()->NewRangeError("invalid_array_buffer_length",
- HandleVector<Object>(NULL, 0)));
- }
-
- allocated_length = static_cast<size_t>(value);
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
+ if (!holder->byte_length()->IsUndefined()) {
+ // ArrayBuffer is already initialized; probably a fuzz test.
+ return *holder;
+ }
+ size_t allocated_length = 0;
+ if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) {
+ return isolate->Throw(
+ *isolate->factory()->NewRangeError("invalid_array_buffer_length",
+ HandleVector<Object>(NULL, 0)));
}
-
if (!Runtime::SetupArrayBufferAllocatingData(isolate,
holder, allocated_length)) {
- return isolate->Throw(*isolate->factory()->
- NewRangeError("invalid_array_buffer_length",
- HandleVector<Object>(NULL, 0)));
+ return isolate->Throw(
+ *isolate->factory()->NewRangeError("invalid_array_buffer_length",
+ HandleVector<Object>(NULL, 0)));
}
-
return *holder;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferGetByteLength) {
+RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
@@ -877,20 +876,21 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferGetByteLength) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferSliceImpl) {
+RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
- CONVERT_DOUBLE_ARG_CHECKED(first, 2);
- size_t start = static_cast<size_t>(first);
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
+ size_t start = 0;
+ RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start));
size_t target_length = NumberToSize(isolate, target->byte_length());
if (target_length == 0) return isolate->heap()->undefined_value();
size_t source_byte_length = NumberToSize(isolate, source->byte_length());
- CHECK(start <= source_byte_length);
- CHECK(source_byte_length - start >= target_length);
+ RUNTIME_ASSERT(start <= source_byte_length);
+ RUNTIME_ASSERT(source_byte_length - start >= target_length);
uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
CopyBytes(target_data, source_data + start, target_length);
@@ -898,18 +898,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferSliceImpl) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferIsView) {
+RUNTIME_FUNCTION(Runtime_ArrayBufferIsView) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(Object, object, 0);
- return object->IsJSArrayBufferView()
- ? isolate->heap()->true_value()
- : isolate->heap()->false_value();
+ return isolate->heap()->ToBoolean(object->IsJSArrayBufferView());
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferNeuter) {
+RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0);
if (array_buffer->backing_store() == NULL) {
CHECK(Smi::FromInt(0) == array_buffer->byte_length());
@@ -949,14 +948,18 @@ void Runtime::ArrayIdToTypeAndSize(
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) {
+RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
HandleScope scope(isolate);
ASSERT(args.length() == 5);
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
CONVERT_SMI_ARG_CHECKED(arrayId, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
- CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset_object, 3);
- CONVERT_ARG_HANDLE_CHECKED(Object, byte_length_object, 4);
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
+
+ RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
+ arrayId <= Runtime::ARRAY_ID_LAST);
+ RUNTIME_ASSERT(maybe_buffer->IsNull() || maybe_buffer->IsJSArrayBuffer());
ASSERT(holder->GetInternalFieldCount() ==
v8::ArrayBufferView::kInternalFieldCount);
@@ -975,19 +978,21 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) {
&fixed_elements_kind,
&element_size);
+ size_t byte_offset = 0;
+ size_t byte_length = 0;
+ RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset));
+ RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length));
+
holder->set_byte_offset(*byte_offset_object);
holder->set_byte_length(*byte_length_object);
- size_t byte_offset = NumberToSize(isolate, *byte_offset_object);
- size_t byte_length = NumberToSize(isolate, *byte_length_object);
-
CHECK_EQ(0, static_cast<int>(byte_length % element_size));
size_t length = byte_length / element_size;
if (length > static_cast<unsigned>(Smi::kMaxValue)) {
- return isolate->Throw(*isolate->factory()->
- NewRangeError("invalid_typed_array_length",
- HandleVector<Object>(NULL, 0)));
+ return isolate->Throw(
+ *isolate->factory()->NewRangeError("invalid_typed_array_length",
+ HandleVector<Object>(NULL, 0)));
}
Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
@@ -997,8 +1002,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) {
size_t array_buffer_byte_length =
NumberToSize(isolate, buffer->byte_length());
- CHECK(byte_offset <= array_buffer_byte_length);
- CHECK(array_buffer_byte_length - byte_offset >= byte_length);
+ RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length);
+ RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length);
holder->set_buffer(*buffer);
holder->set_weak_next(buffer->weak_first_view());
@@ -1010,7 +1015,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) {
static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
Handle<Map> map =
JSObject::GetElementsTransitionMap(holder, external_elements_kind);
- holder->set_map_and_elements(*map, *elements);
+ JSObject::SetMapAndElements(holder, map, elements);
ASSERT(IsExternalArrayElementsKind(holder->map()->elements_kind()));
} else {
holder->set_buffer(Smi::FromInt(0));
@@ -1029,13 +1034,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) {
// initializes backing store using memove.
//
// Returns true if backing store was initialized or false otherwise.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) {
+RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
CONVERT_SMI_ARG_CHECKED(arrayId, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
- CONVERT_ARG_HANDLE_CHECKED(Object, length_obj, 3);
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3);
+
+ RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
+ arrayId <= Runtime::ARRAY_ID_LAST);
ASSERT(holder->GetInternalFieldCount() ==
v8::ArrayBufferView::kInternalFieldCount);
@@ -1059,7 +1067,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) {
JSTypedArray::cast(*source)->type() == array_type) {
length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
}
- size_t length = NumberToSize(isolate, *length_obj);
+ size_t length = 0;
+ RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length));
if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
(length > (kMaxInt / element_size))) {
@@ -1107,7 +1116,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) {
static_cast<uint8_t*>(buffer->backing_store()));
Handle<Map> map = JSObject::GetElementsTransitionMap(
holder, external_elements_kind);
- holder->set_map_and_elements(*map, *elements);
+ JSObject::SetMapAndElements(holder, map, elements);
if (source->IsJSTypedArray()) {
Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
@@ -1122,43 +1131,34 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) {
buffer->backing_store(),
backing_store + source_byte_offset,
byte_length);
- return *isolate->factory()->true_value();
- } else {
- return *isolate->factory()->false_value();
+ return isolate->heap()->true_value();
}
}
- return *isolate->factory()->false_value();
+ return isolate->heap()->false_value();
}
-#define TYPED_ARRAY_GETTER(getter, accessor) \
- RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayGet##getter) { \
+#define BUFFER_VIEW_GETTER(Type, getter, accessor) \
+ RUNTIME_FUNCTION(Runtime_##Type##Get##getter) { \
HandleScope scope(isolate); \
ASSERT(args.length() == 1); \
- CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0); \
- if (!holder->IsJSTypedArray()) \
- return isolate->Throw(*isolate->factory()->NewTypeError( \
- "not_typed_array", HandleVector<Object>(NULL, 0))); \
- Handle<JSTypedArray> typed_array(JSTypedArray::cast(*holder)); \
- return typed_array->accessor(); \
+ CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0); \
+ return holder->accessor(); \
}
-TYPED_ARRAY_GETTER(ByteLength, byte_length)
-TYPED_ARRAY_GETTER(ByteOffset, byte_offset)
-TYPED_ARRAY_GETTER(Length, length)
+BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length)
+BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset)
+BUFFER_VIEW_GETTER(TypedArray, Length, length)
+BUFFER_VIEW_GETTER(DataView, Buffer, buffer)
-#undef TYPED_ARRAY_GETTER
+#undef BUFFER_VIEW_GETTER
-RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayGetBuffer) {
+RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0);
- if (!holder->IsJSTypedArray())
- return isolate->Throw(*isolate->factory()->NewTypeError(
- "not_typed_array", HandleVector<Object>(NULL, 0)));
- Handle<JSTypedArray> typed_array(JSTypedArray::cast(*holder));
- return *typed_array->GetBuffer();
+ CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
+ return *holder->GetBuffer();
}
@@ -1177,22 +1177,24 @@ enum TypedArraySetResultCodes {
};
-RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) {
+RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
HandleScope scope(isolate);
- CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, source_obj, 1);
- CONVERT_ARG_HANDLE_CHECKED(Object, offset_obj, 2);
-
- if (!target_obj->IsJSTypedArray())
+ ASSERT(args.length() == 3);
+ if (!args[0]->IsJSTypedArray())
return isolate->Throw(*isolate->factory()->NewTypeError(
"not_typed_array", HandleVector<Object>(NULL, 0)));
- if (!source_obj->IsJSTypedArray())
+ if (!args[1]->IsJSTypedArray())
return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
+ CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target_obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, source_obj, 1);
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset_obj, 2);
+
Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
- size_t offset = NumberToSize(isolate, *offset_obj);
+ size_t offset = 0;
+ RUNTIME_ASSERT(TryNumberToSize(isolate, *offset_obj, &offset));
size_t target_length = NumberToSize(isolate, target->length());
size_t source_length = NumberToSize(isolate, source->length());
size_t target_byte_length = NumberToSize(isolate, target->byte_length());
@@ -1235,34 +1237,44 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayMaxSizeInHeap) {
- ASSERT_OBJECT_SIZE(FLAG_typed_array_max_size_in_heap);
+RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) {
+ ASSERT(args.length() == 0);
+ ASSERT_OBJECT_SIZE(
+ FLAG_typed_array_max_size_in_heap + FixedTypedArrayBase::kDataOffset);
return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewInitialize) {
+RUNTIME_FUNCTION(Runtime_DataViewInitialize) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
- CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset, 2);
- CONVERT_ARG_HANDLE_CHECKED(Object, byte_length, 3);
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2);
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3);
ASSERT(holder->GetInternalFieldCount() ==
v8::ArrayBufferView::kInternalFieldCount);
for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
holder->SetInternalField(i, Smi::FromInt(0));
}
+ size_t buffer_length = 0;
+ size_t offset = 0;
+ size_t length = 0;
+ RUNTIME_ASSERT(
+ TryNumberToSize(isolate, buffer->byte_length(), &buffer_length));
+ RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset, &offset));
+ RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length, &length));
+
+ // TODO(jkummerow): When we have a "safe numerics" helper class, use it here.
+ // Entire range [offset, offset + length] must be in bounds.
+ RUNTIME_ASSERT(offset <= buffer_length);
+ RUNTIME_ASSERT(offset + length <= buffer_length);
+ // No overflow.
+ RUNTIME_ASSERT(offset + length >= offset);
holder->set_buffer(*buffer);
- ASSERT(byte_offset->IsNumber());
- ASSERT(
- NumberToSize(isolate, buffer->byte_length()) >=
- NumberToSize(isolate, *byte_offset)
- + NumberToSize(isolate, *byte_length));
holder->set_byte_offset(*byte_offset);
- ASSERT(byte_length->IsNumber());
holder->set_byte_length(*byte_length);
holder->set_weak_next(buffer->weak_first_view());
@@ -1272,30 +1284,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewInitialize) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetBuffer) {
- HandleScope scope(isolate);
- ASSERT(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
- return data_view->buffer();
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteOffset) {
- HandleScope scope(isolate);
- ASSERT(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
- return data_view->byte_offset();
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteLength) {
- HandleScope scope(isolate);
- ASSERT(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
- return data_view->byte_length();
-}
-
-
inline static bool NeedToFlipBytes(bool is_little_endian) {
#ifdef V8_TARGET_LITTLE_ENDIAN
return !is_little_endian;
@@ -1411,7 +1399,7 @@ static bool DataViewSetValue(
#define DATA_VIEW_GETTER(TypeName, Type, Converter) \
- RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGet##TypeName) { \
+ RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) { \
HandleScope scope(isolate); \
ASSERT(args.length() == 3); \
CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \
@@ -1420,7 +1408,7 @@ static bool DataViewSetValue(
Type result; \
if (DataViewGetValue( \
isolate, holder, offset, is_little_endian, &result)) { \
- return isolate->heap()->Converter(result); \
+ return *isolate->factory()->Converter(result); \
} else { \
return isolate->Throw(*isolate->factory()->NewRangeError( \
"invalid_data_view_accessor_offset", \
@@ -1428,14 +1416,14 @@ static bool DataViewSetValue(
} \
}
-DATA_VIEW_GETTER(Uint8, uint8_t, NumberFromUint32)
-DATA_VIEW_GETTER(Int8, int8_t, NumberFromInt32)
-DATA_VIEW_GETTER(Uint16, uint16_t, NumberFromUint32)
-DATA_VIEW_GETTER(Int16, int16_t, NumberFromInt32)
-DATA_VIEW_GETTER(Uint32, uint32_t, NumberFromUint32)
-DATA_VIEW_GETTER(Int32, int32_t, NumberFromInt32)
-DATA_VIEW_GETTER(Float32, float, NumberFromDouble)
-DATA_VIEW_GETTER(Float64, double, NumberFromDouble)
+DATA_VIEW_GETTER(Uint8, uint8_t, NewNumberFromUint)
+DATA_VIEW_GETTER(Int8, int8_t, NewNumberFromInt)
+DATA_VIEW_GETTER(Uint16, uint16_t, NewNumberFromUint)
+DATA_VIEW_GETTER(Int16, int16_t, NewNumberFromInt)
+DATA_VIEW_GETTER(Uint32, uint32_t, NewNumberFromUint)
+DATA_VIEW_GETTER(Int32, int32_t, NewNumberFromInt)
+DATA_VIEW_GETTER(Float32, float, NewNumber)
+DATA_VIEW_GETTER(Float64, double, NewNumber)
#undef DATA_VIEW_GETTER
@@ -1493,7 +1481,7 @@ double DataViewConvertValue<double>(double value) {
#define DATA_VIEW_SETTER(TypeName, Type) \
- RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewSet##TypeName) { \
+ RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) { \
HandleScope scope(isolate); \
ASSERT(args.length() == 4); \
CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \
@@ -1523,177 +1511,259 @@ DATA_VIEW_SETTER(Float64, double)
#undef DATA_VIEW_SETTER
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) {
+RUNTIME_FUNCTION(Runtime_SetInitialize) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
- Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0);
+ Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
holder->set_table(*table);
return *holder;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAdd) {
+RUNTIME_FUNCTION(Runtime_SetAdd) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
- Handle<Object> key(args[1], isolate);
- Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
- table = ObjectHashSet::Add(table, key);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
+ table = OrderedHashSet::Add(table, key);
holder->set_table(*table);
return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetHas) {
+RUNTIME_FUNCTION(Runtime_SetHas) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
- Handle<Object> key(args[1], isolate);
- Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
- return isolate->heap()->ToBoolean(table->Contains(*key));
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
+ return isolate->heap()->ToBoolean(table->Contains(key));
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDelete) {
+RUNTIME_FUNCTION(Runtime_SetDelete) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
- Handle<Object> key(args[1], isolate);
- Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
- table = ObjectHashSet::Remove(table, key);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
+ table = OrderedHashSet::Remove(table, key);
holder->set_table(*table);
return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetGetSize) {
+RUNTIME_FUNCTION(Runtime_SetClear) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
- Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
+ Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
+ table = OrderedHashSet::Clear(table);
+ holder->set_table(*table);
+ return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetGetSize) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
+ Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
return Smi::FromInt(table->NumberOfElements());
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_MapInitialize) {
+RUNTIME_FUNCTION(Runtime_SetCreateIterator) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
+ CONVERT_SMI_ARG_CHECKED(kind, 1)
+ RUNTIME_ASSERT(kind == JSSetIterator::kKindValues ||
+ kind == JSSetIterator::kKindEntries);
+ Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
+ return *JSSetIterator::Create(table, kind);
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetIteratorNext) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
+ return *JSSetIterator::Next(holder);
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetIteratorClose) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
+ holder->Close();
+ return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapInitialize) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
- Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0);
+ Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
holder->set_table(*table);
return *holder;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGet) {
+RUNTIME_FUNCTION(Runtime_MapGet) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
- Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
- Handle<Object> lookup(table->Lookup(*key), isolate);
+ Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+ Handle<Object> lookup(table->Lookup(key), isolate);
return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_MapHas) {
+RUNTIME_FUNCTION(Runtime_MapHas) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
- Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
- Handle<Object> lookup(table->Lookup(*key), isolate);
+ Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+ Handle<Object> lookup(table->Lookup(key), isolate);
return isolate->heap()->ToBoolean(!lookup->IsTheHole());
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_MapDelete) {
+RUNTIME_FUNCTION(Runtime_MapDelete) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
- Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
- Handle<Object> lookup(table->Lookup(*key), isolate);
- Handle<ObjectHashTable> new_table =
- ObjectHashTable::Put(table, key, isolate->factory()->the_hole_value());
+ Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+ Handle<Object> lookup(table->Lookup(key), isolate);
+ Handle<OrderedHashMap> new_table =
+ OrderedHashMap::Put(table, key, isolate->factory()->the_hole_value());
holder->set_table(*new_table);
return isolate->heap()->ToBoolean(!lookup->IsTheHole());
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_MapSet) {
+RUNTIME_FUNCTION(Runtime_MapClear) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+ Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+ table = OrderedHashMap::Clear(table);
+ holder->set_table(*table);
+ return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapSet) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
- Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
- Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
+ Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+ Handle<OrderedHashMap> new_table = OrderedHashMap::Put(table, key, value);
holder->set_table(*new_table);
return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGetSize) {
+RUNTIME_FUNCTION(Runtime_MapGetSize) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
- Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+ Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
return Smi::FromInt(table->NumberOfElements());
}
-static JSWeakCollection* WeakCollectionInitialize(Isolate* isolate,
+RUNTIME_FUNCTION(Runtime_MapCreateIterator) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+ CONVERT_SMI_ARG_CHECKED(kind, 1)
+ RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys
+ || kind == JSMapIterator::kKindValues
+ || kind == JSMapIterator::kKindEntries);
+ Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+ return *JSMapIterator::Create(table, kind);
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
+ return *JSMapIterator::Next(holder);
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapIteratorClose) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
+ holder->Close();
+ return isolate->heap()->undefined_value();
+}
+
+
+static Handle<JSWeakCollection> WeakCollectionInitialize(
+ Isolate* isolate,
Handle<JSWeakCollection> weak_collection) {
ASSERT(weak_collection->map()->inobject_properties() == 0);
- Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0);
+ Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
weak_collection->set_table(*table);
weak_collection->set_next(Smi::FromInt(0));
- return *weak_collection;
+ return weak_collection;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionInitialize) {
+RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
- return WeakCollectionInitialize(isolate, weak_collection);
+ return *WeakCollectionInitialize(isolate, weak_collection);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionGet) {
+RUNTIME_FUNCTION(Runtime_WeakCollectionGet) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Handle<ObjectHashTable> table(
ObjectHashTable::cast(weak_collection->table()));
- Handle<Object> lookup(table->Lookup(*key), isolate);
+ Handle<Object> lookup(table->Lookup(key), isolate);
return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionHas) {
+RUNTIME_FUNCTION(Runtime_WeakCollectionHas) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Handle<ObjectHashTable> table(
ObjectHashTable::cast(weak_collection->table()));
- Handle<Object> lookup(table->Lookup(*key), isolate);
+ Handle<Object> lookup(table->Lookup(key), isolate);
return isolate->heap()->ToBoolean(!lookup->IsTheHole());
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionDelete) {
+RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Handle<ObjectHashTable> table(ObjectHashTable::cast(
weak_collection->table()));
- Handle<Object> lookup(table->Lookup(*key), isolate);
+ Handle<Object> lookup(table->Lookup(key), isolate);
Handle<ObjectHashTable> new_table =
ObjectHashTable::Put(table, key, isolate->factory()->the_hole_value());
weak_collection->set_table(*new_table);
@@ -1701,12 +1771,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionDelete) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionSet) {
+RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
- Handle<Object> value(args[2], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
Handle<ObjectHashTable> table(
ObjectHashTable::cast(weak_collection->table()));
Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
@@ -1715,16 +1785,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionSet) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) {
+RUNTIME_FUNCTION(Runtime_ClassOf) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
- Object* obj = args[0];
+ CONVERT_ARG_CHECKED(Object, obj, 0);
if (!obj->IsJSObject()) return isolate->heap()->null_value();
return JSObject::cast(obj)->class_name();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) {
+RUNTIME_FUNCTION(Runtime_GetPrototype) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
@@ -1732,54 +1802,52 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) {
ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
do {
if (obj->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(Handle<JSObject>::cast(obj),
- isolate->factory()->proto_string(),
- v8::ACCESS_GET)) {
- isolate->ReportFailedAccessCheckWrapper(Handle<JSObject>::cast(obj),
- v8::ACCESS_GET);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ !isolate->MayNamedAccess(Handle<JSObject>::cast(obj),
+ isolate->factory()->proto_string(),
+ v8::ACCESS_GET)) {
+ isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(obj),
+ v8::ACCESS_GET);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->undefined_value();
}
- obj = handle(obj->GetPrototype(isolate), isolate);
+ obj = Object::GetPrototype(isolate, obj);
} while (obj->IsJSObject() &&
JSObject::cast(*obj)->map()->is_hidden_prototype());
return *obj;
}
-static inline Object* GetPrototypeSkipHiddenPrototypes(Isolate* isolate,
- Object* receiver) {
- Object* current = receiver->GetPrototype(isolate);
+static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
+ Isolate* isolate, Handle<Object> receiver) {
+ Handle<Object> current = Object::GetPrototype(isolate, receiver);
while (current->IsJSObject() &&
- JSObject::cast(current)->map()->is_hidden_prototype()) {
- current = current->GetPrototype(isolate);
+ JSObject::cast(*current)->map()->is_hidden_prototype()) {
+ current = Object::GetPrototype(isolate, current);
}
return current;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetPrototype) {
+RUNTIME_FUNCTION(Runtime_SetPrototype) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
if (obj->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(obj,
- isolate->factory()->proto_string(),
- v8::ACCESS_SET)) {
- isolate->ReportFailedAccessCheckWrapper(obj, v8::ACCESS_SET);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ !isolate->MayNamedAccess(
+ obj, isolate->factory()->proto_string(), v8::ACCESS_SET)) {
+ isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->undefined_value();
}
if (obj->map()->is_observed()) {
- Handle<Object> old_value(
- GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate);
-
- Handle<Object> result = JSObject::SetPrototype(obj, prototype, true);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> old_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ JSObject::SetPrototype(obj, prototype, true));
- Handle<Object> new_value(
- GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate);
+ Handle<Object> new_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
if (!new_value->SameValue(*old_value)) {
JSObject::EnqueueChangeRecord(obj, "setPrototype",
isolate->factory()->proto_string(),
@@ -1787,22 +1855,24 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetPrototype) {
}
return *result;
}
- Handle<Object> result = JSObject::SetPrototype(obj, prototype, true);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ JSObject::SetPrototype(obj, prototype, true));
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
+ HandleScope shs(isolate);
ASSERT(args.length() == 2);
// See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
- Object* O = args[0];
- Object* V = args[1];
+ CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
while (true) {
- Object* prototype = V->GetPrototype(isolate);
+ Handle<Object> prototype = Object::GetPrototype(isolate, V);
if (prototype->IsNull()) return isolate->heap()->false_value();
- if (O == prototype) return isolate->heap()->true_value();
+ if (*O == *prototype) return isolate->heap()->true_value();
V = prototype;
}
}
@@ -1811,6 +1881,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) {
static bool CheckAccessException(Object* callback,
v8::AccessType access_type) {
DisallowHeapAllocation no_gc;
+ ASSERT(!callback->IsForeign());
if (callback->IsAccessorInfo()) {
AccessorInfo* info = AccessorInfo::cast(callback);
return
@@ -1866,22 +1937,22 @@ static AccessCheckResult CheckPropertyAccess(Handle<JSObject> obj,
if (name->AsArrayIndex(&index)) {
// TODO(1095): we should traverse hidden prototype hierachy as well.
if (CheckGenericAccess(
- obj, obj, index, access_type, &Isolate::MayIndexedAccessWrapper)) {
+ obj, obj, index, access_type, &Isolate::MayIndexedAccess)) {
return ACCESS_ALLOWED;
}
- obj->GetIsolate()->ReportFailedAccessCheckWrapper(obj, access_type);
+ obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type);
return ACCESS_FORBIDDEN;
}
Isolate* isolate = obj->GetIsolate();
LookupResult lookup(isolate);
- obj->LocalLookup(*name, &lookup, true);
+ obj->LocalLookup(name, &lookup, true);
if (!lookup.IsProperty()) return ACCESS_ABSENT;
Handle<JSObject> holder(lookup.holder(), isolate);
if (CheckGenericAccess<Handle<Object> >(
- obj, holder, name, access_type, &Isolate::MayNamedAccessWrapper)) {
+ obj, holder, name, access_type, &Isolate::MayNamedAccess)) {
return ACCESS_ALLOWED;
}
@@ -1898,7 +1969,7 @@ static AccessCheckResult CheckPropertyAccess(Handle<JSObject> obj,
case INTERCEPTOR:
// If the object has an interceptor, try real named properties.
// Overwrite the result to fetch the correct property later.
- holder->LookupRealNamedProperty(*name, &lookup);
+ holder->LookupRealNamedProperty(name, &lookup);
if (lookup.IsProperty() && lookup.IsPropertyCallbacks()) {
if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
return ACCESS_ALLOWED;
@@ -1909,7 +1980,7 @@ static AccessCheckResult CheckPropertyAccess(Handle<JSObject> obj,
break;
}
- isolate->ReportFailedAccessCheckWrapper(obj, access_type);
+ isolate->ReportFailedAccessCheck(obj, access_type);
return ACCESS_FORBIDDEN;
}
@@ -1927,16 +1998,16 @@ enum PropertyDescriptorIndices {
};
-static Handle<Object> GetOwnProperty(Isolate* isolate,
- Handle<JSObject> obj,
- Handle<Name> name) {
+MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
+ Handle<JSObject> obj,
+ Handle<Name> name) {
Heap* heap = isolate->heap();
Factory* factory = isolate->factory();
// Due to some WebKit tests, we want to make sure that we do not log
// more than one access failure here.
AccessCheckResult access_check_result =
CheckPropertyAccess(obj, name, v8::ACCESS_HAS);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
switch (access_check_result) {
case ACCESS_FORBIDDEN: return factory->false_value();
case ACCESS_ALLOWED: break;
@@ -1945,22 +2016,25 @@ static Handle<Object> GetOwnProperty(Isolate* isolate,
PropertyAttributes attrs = JSReceiver::GetLocalPropertyAttribute(obj, name);
if (attrs == ABSENT) {
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return factory->undefined_value();
}
ASSERT(!isolate->has_scheduled_exception());
- AccessorPair* raw_accessors = obj->GetLocalPropertyAccessorPair(*name);
- Handle<AccessorPair> accessors(raw_accessors, isolate);
+ Handle<AccessorPair> accessors;
+ bool has_accessors =
+ JSObject::GetLocalPropertyAccessorPair(obj, name).ToHandle(&accessors);
Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
- elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(raw_accessors != NULL));
+ elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(has_accessors));
- if (raw_accessors == NULL) {
+ if (!has_accessors) {
elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
- // GetProperty does access check.
- Handle<Object> value = GetProperty(isolate, obj, name);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<Object>::null());
+ // Runtime::GetObjectProperty does access check.
+ Handle<Object> value;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, value, Runtime::GetObjectProperty(isolate, obj, name),
+ Object);
elms->set(VALUE_INDEX, *value);
} else {
// Access checks are performed for both accessors separately.
@@ -1972,14 +2046,14 @@ static Handle<Object> GetOwnProperty(Isolate* isolate,
ASSERT(!isolate->has_scheduled_exception());
elms->set(GETTER_INDEX, *getter);
} else {
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
}
if (!setter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_SET)) {
ASSERT(!isolate->has_scheduled_exception());
elms->set(SETTER_INDEX, *setter);
} else {
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
}
}
@@ -1994,28 +2068,30 @@ static Handle<Object> GetOwnProperty(Isolate* isolate,
// [false, value, Writeable, Enumerable, Configurable]
// if args[1] is an accessor on args[0]
// [true, GetFunction, SetFunction, Enumerable, Configurable]
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
+RUNTIME_FUNCTION(Runtime_GetOwnProperty) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
- Handle<Object> result = GetOwnProperty(isolate, obj, name);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, GetOwnProperty(isolate, obj, name));
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_PreventExtensions) {
+RUNTIME_FUNCTION(Runtime_PreventExtensions) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
- Handle<Object> result = JSObject::PreventExtensions(obj);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, JSObject::PreventExtensions(obj));
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsExtensible) {
+RUNTIME_FUNCTION(Runtime_IsExtensible) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSObject, obj, 0);
@@ -2029,44 +2105,46 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsExtensible) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpCompile) {
+RUNTIME_FUNCTION(Runtime_RegExpCompile) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
- Handle<Object> result = RegExpImpl::Compile(re, pattern, flags);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, RegExpImpl::Compile(re, pattern, flags));
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateApiFunction) {
+RUNTIME_FUNCTION(Runtime_CreateApiFunction) {
HandleScope scope(isolate);
- ASSERT(args.length() == 1);
+ ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
- return *isolate->factory()->CreateApiFunction(data);
+ CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
+ return *isolate->factory()->CreateApiFunction(data, prototype);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsTemplate) {
+RUNTIME_FUNCTION(Runtime_IsTemplate) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
- Object* arg = args[0];
+ CONVERT_ARG_HANDLE_CHECKED(Object, arg, 0);
bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
return isolate->heap()->ToBoolean(result);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetTemplateField) {
+RUNTIME_FUNCTION(Runtime_GetTemplateField) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_CHECKED(HeapObject, templ, 0);
- CONVERT_SMI_ARG_CHECKED(index, 1)
+ CONVERT_SMI_ARG_CHECKED(index, 1);
int offset = index * kPointerSize + HeapObject::kHeaderSize;
InstanceType type = templ->map()->instance_type();
- RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE ||
- type == OBJECT_TEMPLATE_INFO_TYPE);
+ RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE ||
+ type == OBJECT_TEMPLATE_INFO_TYPE);
RUNTIME_ASSERT(offset > 0);
if (type == FUNCTION_TEMPLATE_INFO_TYPE) {
RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize);
@@ -2077,38 +2155,40 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetTemplateField) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DisableAccessChecks) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_DisableAccessChecks) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(HeapObject, object, 0);
- Map* old_map = object->map();
+ CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
+ Handle<Map> old_map(object->map());
bool needs_access_checks = old_map->is_access_check_needed();
if (needs_access_checks) {
// Copy map so it won't interfere constructor's initial map.
- Map* new_map;
- MaybeObject* maybe_new_map = old_map->Copy();
- if (!maybe_new_map->To(&new_map)) return maybe_new_map;
-
+ Handle<Map> new_map = Map::Copy(old_map);
new_map->set_is_access_check_needed(false);
- object->set_map(new_map);
+ if (object->IsJSObject()) {
+ JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
+ } else {
+ object->set_map(*new_map);
+ }
}
return isolate->heap()->ToBoolean(needs_access_checks);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_EnableAccessChecks) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_EnableAccessChecks) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(HeapObject, object, 0);
- Map* old_map = object->map();
+ CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
+ Handle<Map> old_map(object->map());
if (!old_map->is_access_check_needed()) {
// Copy map so it won't interfere constructor's initial map.
- Map* new_map;
- MaybeObject* maybe_new_map = old_map->Copy();
- if (!maybe_new_map->To(&new_map)) return maybe_new_map;
-
+ Handle<Map> new_map = Map::Copy(old_map);
new_map->set_is_access_check_needed(true);
- object->set_map(new_map);
+ if (object->IsJSObject()) {
+ JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
+ } else {
+ object->set_map(*new_map);
+ }
}
return isolate->heap()->undefined_value();
}
@@ -2124,7 +2204,7 @@ static Handle<Object> InstantiateAccessorComponent(Isolate* isolate,
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAccessorProperty) {
+RUNTIME_FUNCTION(Runtime_SetAccessorProperty) {
HandleScope scope(isolate);
ASSERT(args.length() == 6);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
@@ -2135,6 +2215,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAccessorProperty) {
CONVERT_SMI_ARG_CHECKED(access_control, 5);
RUNTIME_ASSERT(getter->IsUndefined() || getter->IsFunctionTemplateInfo());
RUNTIME_ASSERT(setter->IsUndefined() || setter->IsFunctionTemplateInfo());
+ RUNTIME_ASSERT(PropertyDetails::AttributesField::is_valid(
+ static_cast<PropertyAttributes>(attribute)));
JSObject::DefineAccessor(object,
name,
InstantiateAccessorComponent(isolate, getter),
@@ -2145,26 +2227,22 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAccessorProperty) {
}
-static Failure* ThrowRedeclarationError(Isolate* isolate,
- const char* type,
- Handle<String> name) {
+static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
HandleScope scope(isolate);
- Handle<Object> type_handle =
- isolate->factory()->NewStringFromAscii(CStrVector(type));
- Handle<Object> args[2] = { type_handle, name };
- Handle<Object> error =
- isolate->factory()->NewTypeError("redeclaration", HandleVector(args, 2));
+ Handle<Object> args[1] = { name };
+ Handle<Object> error = isolate->factory()->NewTypeError(
+ "var_redeclaration", HandleVector(args, 1));
return isolate->Throw(*error);
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeclareGlobals) {
+RUNTIME_FUNCTION(RuntimeHidden_DeclareGlobals) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
Handle<GlobalObject> global = Handle<GlobalObject>(
isolate->context()->global_object());
- Handle<Context> context = args.at<Context>(0);
+ CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
CONVERT_SMI_ARG_CHECKED(flags, 2);
@@ -2188,7 +2266,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeclareGlobals) {
// value of the variable if the property is already there.
// Do the lookup locally only, see ES5 erratum.
LookupResult lookup(isolate);
- global->LocalLookup(*name, &lookup, true);
+ global->LocalLookup(name, &lookup, true);
if (lookup.IsFound()) {
// We found an existing property. Unless it was an interceptor
// that claims the property is absent, skip this declaration.
@@ -2208,7 +2286,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeclareGlobals) {
}
LookupResult lookup(isolate);
- global->LocalLookup(*name, &lookup, true);
+ global->LocalLookup(name, &lookup, true);
// Compute the property attributes. According to ECMA-262,
// the property must be non-configurable except in eval.
@@ -2230,18 +2308,19 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeclareGlobals) {
if (lookup.IsFound() && lookup.IsDontDelete()) {
if (lookup.IsReadOnly() || lookup.IsDontEnum() ||
lookup.IsPropertyCallbacks()) {
- return ThrowRedeclarationError(isolate, "function", name);
+ return ThrowRedeclarationError(isolate, name);
}
// If the existing property is not configurable, keep its attributes.
attr = lookup.GetAttributes();
}
// Define or redefine own property.
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
global, name, value, static_cast<PropertyAttributes>(attr)));
} else {
// Do a [[Put]] on the existing (own) property.
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
JSObject::SetProperty(
global, name, value, static_cast<PropertyAttributes>(attr),
strict_mode));
@@ -2253,20 +2332,20 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeclareGlobals) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeclareContextSlot) {
+RUNTIME_FUNCTION(RuntimeHidden_DeclareContextSlot) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
// Declarations are always made in a function or native context. In the
// case of eval code, the context passed is the context of the caller,
// which may be some nested context and not the declaration context.
- RUNTIME_ASSERT(args[0]->IsContext());
- Handle<Context> context(Context::cast(args[0])->declaration_context());
-
- Handle<String> name(String::cast(args[1]));
- PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2));
+ CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0);
+ Handle<Context> context(context_arg->declaration_context());
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
+ CONVERT_SMI_ARG_CHECKED(mode_arg, 2);
+ PropertyAttributes mode = static_cast<PropertyAttributes>(mode_arg);
RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
- Handle<Object> initial_value(args[3], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3);
int index;
PropertyAttributes attributes;
@@ -2282,8 +2361,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeclareContextSlot) {
if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) {
// Functions are not read-only.
ASSERT(mode != READ_ONLY || initial_value->IsTheHole());
- const char* type = ((attributes & READ_ONLY) != 0) ? "const" : "var";
- return ThrowRedeclarationError(isolate, type, name);
+ return ThrowRedeclarationError(isolate, name);
}
// Initialize it if necessary.
@@ -2298,7 +2376,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeclareContextSlot) {
// Slow case: The property is in the context extension object of a
// function context or the global object of a native context.
Handle<JSObject> object = Handle<JSObject>::cast(holder);
- RETURN_IF_EMPTY_HANDLE(
+ RETURN_FAILURE_ON_EXCEPTION(
isolate,
JSReceiver::SetProperty(object, name, initial_value, mode, SLOPPY));
}
@@ -2335,17 +2413,17 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeclareContextSlot) {
if (initial_value->IsTheHole() &&
!object->IsJSContextExtensionObject()) {
LookupResult lookup(isolate);
- object->Lookup(*name, &lookup);
+ object->Lookup(name, &lookup);
if (lookup.IsPropertyCallbacks()) {
- return ThrowRedeclarationError(isolate, "const", name);
+ return ThrowRedeclarationError(isolate, name);
}
}
if (object->IsJSGlobalObject()) {
// Define own property on the global object.
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(object, name, value, mode));
} else {
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSReceiver::SetProperty(object, name, value, mode, SLOPPY));
}
}
@@ -2354,7 +2432,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeclareContextSlot) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
+RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
HandleScope scope(isolate);
// args[0] == name
// args[1] == language_mode
@@ -2366,7 +2444,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
bool assign = args.length() == 3;
CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
- RUNTIME_ASSERT(args[1]->IsSmi());
CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
// According to ECMA-262, section 12.2, page 62, the property must
@@ -2381,7 +2458,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
// Note that objects can have hidden prototypes, so we need to traverse
// the whole chain of hidden prototypes to do a 'local' lookup.
LookupResult lookup(isolate);
- isolate->context()->global_object()->LocalLookup(*name, &lookup, true);
+ isolate->context()->global_object()->LocalLookup(name, &lookup, true);
if (lookup.IsInterceptor()) {
Handle<JSObject> holder(lookup.holder());
PropertyAttributes intercepted =
@@ -2390,9 +2467,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
// Found an interceptor that's not read only.
if (assign) {
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
- Handle<Object> result = JSObject::SetPropertyForResult(
- holder, &lookup, name, value, attributes, strict_mode);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ JSObject::SetPropertyForResult(
+ holder, &lookup, name, value, attributes, strict_mode));
return *result;
} else {
return isolate->heap()->undefined_value();
@@ -2403,23 +2482,24 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
if (assign) {
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
Handle<GlobalObject> global(isolate->context()->global_object());
- Handle<Object> result = JSReceiver::SetProperty(
- global, name, value, attributes, strict_mode);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ JSReceiver::SetProperty(global, name, value, attributes, strict_mode));
return *result;
}
return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_InitializeConstGlobal) {
+RUNTIME_FUNCTION(RuntimeHidden_InitializeConstGlobal) {
SealHandleScope shs(isolate);
// All constants are declared with an initial value. The name
// of the constant is the first argument and the initial value
// is the second.
RUNTIME_ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
- Handle<Object> value = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
// Get the current global object from top.
GlobalObject* global = isolate->context()->global_object();
@@ -2435,11 +2515,11 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_InitializeConstGlobal) {
// prototype chain (this rules out using SetProperty).
// We use SetLocalPropertyIgnoreAttributes instead
LookupResult lookup(isolate);
- global->LocalLookup(*name, &lookup);
+ global->LocalLookup(name, &lookup);
if (!lookup.IsFound()) {
HandleScope handle_scope(isolate);
Handle<GlobalObject> global(isolate->context()->global_object());
- RETURN_IF_EMPTY_HANDLE(
+ RETURN_FAILURE_ON_EXCEPTION(
isolate,
JSObject::SetLocalPropertyIgnoreAttributes(global, name, value,
attributes));
@@ -2456,7 +2536,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_InitializeConstGlobal) {
// property through an interceptor and only do it if it's
// uninitialized, e.g. the hole. Nirk...
// Passing sloppy mode because the property is writable.
- RETURN_IF_EMPTY_HANDLE(
+ RETURN_FAILURE_ON_EXCEPTION(
isolate,
JSReceiver::SetProperty(global, name, value, attributes, SLOPPY));
return *value;
@@ -2489,18 +2569,16 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_InitializeConstGlobal) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_InitializeConstContextSlot) {
+RUNTIME_FUNCTION(RuntimeHidden_InitializeConstContextSlot) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- Handle<Object> value(args[0], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
ASSERT(!value->IsTheHole());
-
// Initializations are always done in a function or native context.
- RUNTIME_ASSERT(args[1]->IsContext());
- Handle<Context> context(Context::cast(args[1])->declaration_context());
-
- Handle<String> name(String::cast(args[2]));
+ CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1);
+ Handle<Context> context(context_arg->declaration_context());
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
int index;
PropertyAttributes attributes;
@@ -2526,7 +2604,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_InitializeConstContextSlot) {
Handle<JSObject> global = Handle<JSObject>(
isolate->context()->global_object());
// Strict mode not needed (const disallowed in strict mode).
- RETURN_IF_EMPTY_HANDLE(
+ RETURN_FAILURE_ON_EXCEPTION(
isolate,
JSReceiver::SetProperty(global, name, value, NONE, SLOPPY));
return *value;
@@ -2553,7 +2631,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_InitializeConstContextSlot) {
// Set it if it hasn't been set before. NOTE: We cannot use
// GetProperty() to get the current value as it 'unholes' the value.
LookupResult lookup(isolate);
- object->LocalLookupRealNamedProperty(*name, &lookup);
+ object->LocalLookupRealNamedProperty(name, &lookup);
ASSERT(lookup.IsFound()); // the property was declared
ASSERT(lookup.IsReadOnly()); // and it was declared as read-only
@@ -2577,7 +2655,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_InitializeConstContextSlot) {
// read-only property.
if ((attributes & READ_ONLY) == 0) {
// Strict mode not needed (const disallowed in strict mode).
- RETURN_IF_EMPTY_HANDLE(
+ RETURN_FAILURE_ON_EXCEPTION(
isolate,
JSReceiver::SetProperty(object, name, value, attributes, SLOPPY));
}
@@ -2587,12 +2665,13 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_InitializeConstContextSlot) {
}
-RUNTIME_FUNCTION(MaybeObject*,
- Runtime_OptimizeObjectForAddingMultipleProperties) {
+RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_SMI_ARG_CHECKED(properties, 1);
+ // Conservative upper limit to prevent fuzz tests from going OOM.
+ RUNTIME_ASSERT(properties <= 100000);
if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
}
@@ -2600,7 +2679,7 @@ RUNTIME_FUNCTION(MaybeObject*,
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_RegExpExec) {
+RUNTIME_FUNCTION(RuntimeHidden_RegExpExec) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
@@ -2612,52 +2691,36 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_RegExpExec) {
RUNTIME_ASSERT(index >= 0);
RUNTIME_ASSERT(index <= subject->length());
isolate->counters()->regexp_entry_runtime()->Increment();
- Handle<Object> result = RegExpImpl::Exec(regexp,
- subject,
- index,
- last_match_info);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ RegExpImpl::Exec(regexp, subject, index, last_match_info));
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_RegExpConstructResult) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(RuntimeHidden_RegExpConstructResult) {
+ HandleScope handle_scope(isolate);
ASSERT(args.length() == 3);
- CONVERT_SMI_ARG_CHECKED(elements_count, 0);
- if (elements_count < 0 ||
- elements_count > FixedArray::kMaxLength ||
- !Smi::IsValid(elements_count)) {
- return isolate->ThrowIllegalOperation();
- }
- Object* new_object;
- { MaybeObject* maybe_new_object =
- isolate->heap()->AllocateFixedArray(elements_count);
- if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object;
- }
- FixedArray* elements = FixedArray::cast(new_object);
- { MaybeObject* maybe_new_object = isolate->heap()->AllocateRaw(
- JSRegExpResult::kSize, NEW_SPACE, OLD_POINTER_SPACE);
- if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object;
- }
- {
- DisallowHeapAllocation no_gc;
- HandleScope scope(isolate);
- reinterpret_cast<HeapObject*>(new_object)->
- set_map(isolate->native_context()->regexp_result_map());
- }
- JSArray* array = JSArray::cast(new_object);
- array->set_properties(isolate->heap()->empty_fixed_array());
- array->set_elements(elements);
- array->set_length(Smi::FromInt(elements_count));
+ CONVERT_SMI_ARG_CHECKED(size, 0);
+ RUNTIME_ASSERT(size >= 0 && size <= FixedArray::kMaxLength);
+ CONVERT_ARG_HANDLE_CHECKED(Object, index, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, input, 2);
+ Handle<FixedArray> elements = isolate->factory()->NewFixedArray(size);
+ Handle<Map> regexp_map(isolate->native_context()->regexp_result_map());
+ Handle<JSObject> object =
+ isolate->factory()->NewJSObjectFromMap(regexp_map, NOT_TENURED, false);
+ Handle<JSArray> array = Handle<JSArray>::cast(object);
+ array->set_elements(*elements);
+ array->set_length(Smi::FromInt(size));
// Write in-object properties after the length of the array.
- array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]);
- array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]);
- return array;
+ array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, *index);
+ array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input);
+ return *array;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) {
+RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
HandleScope scope(isolate);
ASSERT(args.length() == 5);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
@@ -2701,24 +2764,27 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) {
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
Handle<Object> zero(Smi::FromInt(0), isolate);
Factory* factory = isolate->factory();
- CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
- regexp, factory->source_string(), source, final));
- CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
- regexp, factory->global_string(), global, final));
- CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
- regexp, factory->ignore_case_string(), ignoreCase, final));
- CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
- regexp, factory->multiline_string(), multiline, final));
- CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
- regexp, factory->last_index_string(), zero, writable));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ regexp, factory->source_string(), source, final).Check();
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ regexp, factory->global_string(), global, final).Check();
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ regexp, factory->ignore_case_string(), ignoreCase, final).Check();
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ regexp, factory->multiline_string(), multiline, final).Check();
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ regexp, factory->last_index_string(), zero, writable).Check();
return *regexp;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FinishArrayPrototypeSetup) {
+RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
+ Object* length = prototype->length();
+ RUNTIME_ASSERT(length->IsSmi() && Smi::cast(length)->value() == 0);
+ RUNTIME_ASSERT(prototype->HasFastSmiOrObjectElements());
// This is necessary to enable fast checks for absence of elements
// on Array.prototype and below.
prototype->set_elements(isolate->heap()->empty_fixed_array());
@@ -2733,18 +2799,19 @@ static Handle<JSFunction> InstallBuiltin(Isolate* isolate,
Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
Handle<Code> code(isolate->builtins()->builtin(builtin_name));
Handle<JSFunction> optimized =
- isolate->factory()->NewFunction(key,
+ isolate->factory()->NewFunction(MaybeHandle<Object>(),
+ key,
JS_OBJECT_TYPE,
JSObject::kHeaderSize,
code,
false);
optimized->shared()->DontAdaptArguments();
- JSReceiver::SetProperty(holder, key, optimized, NONE, STRICT);
+ JSReceiver::SetProperty(holder, key, optimized, NONE, STRICT).Assert();
return optimized;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SpecialArrayFunctions) {
+RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, holder, 0);
@@ -2761,16 +2828,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SpecialArrayFunctions) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsSloppyModeFunction) {
+RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
if (!callable->IsJSFunction()) {
HandleScope scope(isolate);
- bool threw = false;
- Handle<Object> delegate = Execution::TryGetFunctionDelegate(
- isolate, Handle<JSReceiver>(callable), &threw);
- if (threw) return Failure::Exception();
+ Handle<Object> delegate;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, delegate,
+ Execution::TryGetFunctionDelegate(
+ isolate, Handle<JSReceiver>(callable)));
callable = JSFunction::cast(*delegate);
}
JSFunction* function = JSFunction::cast(callable);
@@ -2779,17 +2847,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsSloppyModeFunction) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultReceiver) {
+RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
if (!callable->IsJSFunction()) {
HandleScope scope(isolate);
- bool threw = false;
- Handle<Object> delegate = Execution::TryGetFunctionDelegate(
- isolate, Handle<JSReceiver>(callable), &threw);
- if (threw) return Failure::Exception();
+ Handle<Object> delegate;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, delegate,
+ Execution::TryGetFunctionDelegate(
+ isolate, Handle<JSReceiver>(callable)));
callable = JSFunction::cast(*delegate);
}
JSFunction* function = JSFunction::cast(callable);
@@ -2807,13 +2876,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultReceiver) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_MaterializeRegExpLiteral) {
+RUNTIME_FUNCTION(RuntimeHidden_MaterializeRegExpLiteral) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
- int index = args.smi_at(1);
- Handle<String> pattern = args.at<String>(2);
- Handle<String> flags = args.at<String>(3);
+ CONVERT_SMI_ARG_CHECKED(index, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
+ CONVERT_ARG_HANDLE_CHECKED(String, flags, 3);
// Get the RegExp function from the context in the literals array.
// This is the RegExp function from the context in which the
@@ -2824,20 +2893,16 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_MaterializeRegExpLiteral) {
Handle<JSFunction>(
JSFunction::NativeContextFromLiterals(*literals)->regexp_function());
// Compute the regular expression literal.
- bool has_pending_exception;
- Handle<Object> regexp =
- RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags,
- &has_pending_exception);
- if (has_pending_exception) {
- ASSERT(isolate->has_pending_exception());
- return Failure::Exception();
- }
+ Handle<Object> regexp;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, regexp,
+ RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags));
literals->set(index, *regexp);
return *regexp;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetName) {
+RUNTIME_FUNCTION(Runtime_FunctionGetName) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
@@ -2846,7 +2911,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetName) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetName) {
+RUNTIME_FUNCTION(Runtime_FunctionSetName) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
@@ -2857,7 +2922,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetName) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionNameShouldPrintAsAnonymous) {
+RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
@@ -2866,7 +2931,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionNameShouldPrintAsAnonymous) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
+RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
@@ -2875,7 +2940,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsGenerator) {
+RUNTIME_FUNCTION(Runtime_FunctionIsGenerator) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
@@ -2883,18 +2948,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsGenerator) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionRemovePrototype) {
+RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
- f->RemovePrototype();
+ RUNTIME_ASSERT(f->RemovePrototype());
return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetScript) {
+RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
@@ -2902,11 +2967,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetScript) {
Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
if (!script->IsScript()) return isolate->heap()->undefined_value();
- return *GetScriptWrapper(Handle<Script>::cast(script));
+ return *Script::GetWrapper(Handle<Script>::cast(script));
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetSourceCode) {
+RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
@@ -2916,7 +2981,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetSourceCode) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetScriptSourcePosition) {
+RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
@@ -2926,7 +2991,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetScriptSourcePosition) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetPositionForOffset) {
+RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
@@ -2940,7 +3005,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetPositionForOffset) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetInstanceClassName) {
+RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
@@ -2951,7 +3016,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetInstanceClassName) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetLength) {
+RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
@@ -2962,7 +3027,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetLength) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetPrototype) {
+RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -2974,35 +3039,36 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetPrototype) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_FunctionSetReadOnlyPrototype) {
+ HandleScope shs(isolate);
RUNTIME_ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSFunction, function, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
- String* name = isolate->heap()->prototype_string();
+ Handle<String> name = isolate->factory()->prototype_string();
if (function->HasFastProperties()) {
// Construct a new field descriptor with updated attributes.
- DescriptorArray* instance_desc = function->map()->instance_descriptors();
+ Handle<DescriptorArray> instance_desc =
+ handle(function->map()->instance_descriptors());
- int index = instance_desc->SearchWithCache(name, function->map());
+ int index = instance_desc->SearchWithCache(*name, function->map());
ASSERT(index != DescriptorArray::kNotFound);
PropertyDetails details = instance_desc->GetDetails(index);
- CallbacksDescriptor new_desc(name,
- instance_desc->GetValue(index),
+ CallbacksDescriptor new_desc(
+ name,
+ handle(instance_desc->GetValue(index), isolate),
static_cast<PropertyAttributes>(details.attributes() | READ_ONLY));
// Create a new map featuring the new field descriptors array.
- Map* new_map;
- MaybeObject* maybe_map =
- function->map()->CopyReplaceDescriptor(
- instance_desc, &new_desc, index, OMIT_TRANSITION);
- if (!maybe_map->To(&new_map)) return maybe_map;
+ Handle<Map> map = handle(function->map());
+ Handle<Map> new_map = Map::CopyReplaceDescriptor(
+ map, instance_desc, &new_desc, index, OMIT_TRANSITION);
- function->set_map(new_map);
+ JSObject::MigrateToMap(function, new_map);
} else { // Dictionary properties.
// Directly manipulate the property details.
+ DisallowHeapAllocation no_gc;
int entry = function->property_dictionary()->FindEntry(name);
ASSERT(entry != NameDictionary::kNotFound);
PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
@@ -3012,11 +3078,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
details.dictionary_index());
function->property_dictionary()->DetailsAtPut(entry, new_details);
}
- return function;
+ return *function;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) {
+RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
@@ -3025,7 +3091,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsBuiltin) {
+RUNTIME_FUNCTION(Runtime_FunctionIsBuiltin) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
@@ -3034,21 +3100,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsBuiltin) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
+RUNTIME_FUNCTION(Runtime_SetCode) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
- Handle<Object> code = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
- if (code->IsNull()) return *target;
- RUNTIME_ASSERT(code->IsJSFunction());
- Handle<JSFunction> source = Handle<JSFunction>::cast(code);
Handle<SharedFunctionInfo> target_shared(target->shared());
Handle<SharedFunctionInfo> source_shared(source->shared());
+ RUNTIME_ASSERT(!source_shared->bound());
if (!Compiler::EnsureCompiled(source, KEEP_EXCEPTION)) {
- return Failure::Exception();
+ return isolate->heap()->exception();
}
// Mark both, the source and the target, as un-flushable because the
@@ -3063,6 +3127,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
target_shared->ReplaceCode(source_shared->code());
target_shared->set_scope_info(source_shared->scope_info());
target_shared->set_length(source_shared->length());
+ target_shared->set_feedback_vector(source_shared->feedback_vector());
target_shared->set_formal_parameter_count(
source_shared->formal_parameter_count());
target_shared->set_script(source_shared->script());
@@ -3072,6 +3137,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
bool was_native = target_shared->native();
target_shared->set_compiler_hints(source_shared->compiler_hints());
target_shared->set_native(was_native);
+ target_shared->set_profiler_ticks(source_shared->profiler_ticks());
// Set the code of the target function.
target->ReplaceCode(source_shared->code());
@@ -3100,7 +3166,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) {
+RUNTIME_FUNCTION(Runtime_SetExpectedNumberOfProperties) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
@@ -3114,9 +3180,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) {
if (!func->shared()->live_objects_may_exist()) {
func->shared()->set_expected_nof_properties(num);
if (func->has_initial_map()) {
- Handle<Map> new_initial_map =
- func->GetIsolate()->factory()->CopyMap(
- Handle<Map>(func->initial_map()));
+ Handle<Map> new_initial_map = Map::Copy(handle(func->initial_map()));
new_initial_map->set_unused_property_fields(num);
func->set_initial_map(*new_initial_map);
}
@@ -3125,7 +3189,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_CreateJSGeneratorObject) {
+RUNTIME_FUNCTION(RuntimeHidden_CreateJSGeneratorObject) {
HandleScope scope(isolate);
ASSERT(args.length() == 0);
@@ -3151,10 +3215,10 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_CreateJSGeneratorObject) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_SuspendJSGeneratorObject) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(RuntimeHidden_SuspendJSGeneratorObject) {
+ HandleScope handle_scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0);
JavaScriptFrameIterator stack_iterator(isolate);
JavaScriptFrame* frame = stack_iterator.frame();
@@ -3183,11 +3247,10 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_SuspendJSGeneratorObject) {
ASSERT(!frame->HasHandler());
} else {
int stack_handler_index = -1;
- MaybeObject* alloc = isolate->heap()->AllocateFixedArray(operands_count);
- FixedArray* operand_stack;
- if (!alloc->To(&operand_stack)) return alloc;
- frame->SaveOperandStack(operand_stack, &stack_handler_index);
- generator_object->set_operand_stack(operand_stack);
+ Handle<FixedArray> operand_stack =
+ isolate->factory()->NewFixedArray(operands_count);
+ frame->SaveOperandStack(*operand_stack, &stack_handler_index);
+ generator_object->set_operand_stack(*operand_stack);
generator_object->set_stack_handler_index(stack_handler_index);
}
@@ -3202,7 +3265,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_SuspendJSGeneratorObject) {
// inlined into GeneratorNext and GeneratorThrow. EmitGeneratorResumeResume is
// called in any case, as it needs to reconstruct the stack frame and make space
// for arguments and operands.
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_ResumeJSGeneratorObject) {
+RUNTIME_FUNCTION(RuntimeHidden_ResumeJSGeneratorObject) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
@@ -3250,7 +3313,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_ResumeJSGeneratorObject) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_ThrowGeneratorStateError) {
+RUNTIME_FUNCTION(RuntimeHidden_ThrowGeneratorStateError) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
@@ -3263,41 +3326,27 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_ThrowGeneratorStateError) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ObjectFreeze) {
+RUNTIME_FUNCTION(Runtime_ObjectFreeze) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
- Handle<Object> result = JSObject::Freeze(object);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object));
return *result;
}
-MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate,
- Object* char_code) {
- if (char_code->IsNumber()) {
- return isolate->heap()->LookupSingleCharacterStringFromCode(
- NumberToUint32(char_code) & 0xffff);
- }
- return isolate->heap()->empty_string();
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_StringCharCodeAt) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(RuntimeHidden_StringCharCodeAt) {
+ HandleScope handle_scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(String, subject, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]);
// Flatten the string. If someone wants to get a char at an index
// in a cons string, it is likely that more indices will be
// accessed.
- Object* flat;
- { MaybeObject* maybe_flat = subject->TryFlatten();
- if (!maybe_flat->ToObject(&flat)) return maybe_flat;
- }
- subject = String::cast(flat);
+ subject = String::Flatten(subject);
if (i >= static_cast<uint32_t>(subject->length())) {
return isolate->heap()->nan_value();
@@ -3307,10 +3356,15 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_StringCharCodeAt) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CharFromCode) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_CharFromCode) {
+ HandleScope handlescope(isolate);
ASSERT(args.length() == 1);
- return CharFromCode(isolate, args[0]);
+ if (args[0]->IsNumber()) {
+ CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]);
+ code &= 0xffff;
+ return *isolate->factory()->LookupSingleCharacterStringFromCode(code);
+ }
+ return isolate->heap()->empty_string();
}
@@ -3470,15 +3524,20 @@ class ReplacementStringBuilder {
}
- Handle<String> ToString() {
+ MaybeHandle<String> ToString() {
+ Isolate* isolate = heap_->isolate();
if (array_builder_.length() == 0) {
- return heap_->isolate()->factory()->empty_string();
+ return isolate->factory()->empty_string();
}
Handle<String> joined_string;
if (is_ascii_) {
- Handle<SeqOneByteString> seq = NewRawOneByteString(character_count_);
- RETURN_IF_EMPTY_HANDLE_VALUE(heap_->isolate(), seq, Handle<String>());
+ Handle<SeqOneByteString> seq;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, seq,
+ isolate->factory()->NewRawOneByteString(character_count_),
+ String);
+
DisallowHeapAllocation no_gc;
uint8_t* char_buffer = seq->GetChars();
StringBuilderConcatHelper(*subject_,
@@ -3488,8 +3547,12 @@ class ReplacementStringBuilder {
joined_string = Handle<String>::cast(seq);
} else {
// Non-ASCII.
- Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_);
- RETURN_IF_EMPTY_HANDLE_VALUE(heap_->isolate(), seq, Handle<String>());
+ Handle<SeqTwoByteString> seq;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, seq,
+ isolate->factory()->NewRawTwoByteString(character_count_),
+ String);
+
DisallowHeapAllocation no_gc;
uc16* char_buffer = seq->GetChars();
StringBuilderConcatHelper(*subject_,
@@ -3512,16 +3575,6 @@ class ReplacementStringBuilder {
}
private:
- Handle<SeqOneByteString> NewRawOneByteString(int length) {
- return heap_->isolate()->factory()->NewRawOneByteString(length);
- }
-
-
- Handle<SeqTwoByteString> NewRawTwoByteString(int length) {
- return heap_->isolate()->factory()->NewRawTwoByteString(length);
- }
-
-
void AddElement(Object* element) {
ASSERT(element->IsSmi() || element->IsString());
ASSERT(array_builder_.capacity() > array_builder_.length());
@@ -3959,7 +4012,7 @@ void FindStringIndicesDispatch(Isolate* isolate,
template<typename ResultSeqString>
-MUST_USE_RESULT static MaybeObject* StringReplaceGlobalAtomRegExpWithString(
+MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString(
Isolate* isolate,
Handle<String> subject,
Handle<JSRegExp> pattern_regexp,
@@ -4000,14 +4053,15 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalAtomRegExpWithString(
int subject_pos = 0;
int result_pos = 0;
- Handle<String> result_seq;
+ MaybeHandle<SeqString> maybe_res;
if (ResultSeqString::kHasAsciiEncoding) {
- result_seq = isolate->factory()->NewRawOneByteString(result_len);
+ maybe_res = isolate->factory()->NewRawOneByteString(result_len);
} else {
- result_seq = isolate->factory()->NewRawTwoByteString(result_len);
+ maybe_res = isolate->factory()->NewRawTwoByteString(result_len);
}
- RETURN_IF_EMPTY_HANDLE(isolate, result_seq);
- Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(result_seq);
+ Handle<SeqString> untyped_res;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res);
+ Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res);
for (int i = 0; i < matches; i++) {
// Copy non-matched subject content.
@@ -4046,7 +4100,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalAtomRegExpWithString(
}
-MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithString(
+MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString(
Isolate* isolate,
Handle<String> subject,
Handle<JSRegExp> regexp,
@@ -4078,11 +4132,11 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithString(
}
RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
- if (global_cache.HasException()) return Failure::Exception();
+ if (global_cache.HasException()) return isolate->heap()->exception();
int32_t* current_match = global_cache.FetchNext();
if (current_match == NULL) {
- if (global_cache.HasException()) return Failure::Exception();
+ if (global_cache.HasException()) return isolate->heap()->exception();
return *subject;
}
@@ -4124,7 +4178,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithString(
current_match = global_cache.FetchNext();
} while (current_match != NULL);
- if (global_cache.HasException()) return Failure::Exception();
+ if (global_cache.HasException()) return isolate->heap()->exception();
if (prev < subject_length) {
builder.EnsureCapacity(2);
@@ -4136,14 +4190,14 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithString(
capture_count,
global_cache.LastSuccessfulMatch());
- Handle<String> result = builder.ToString();
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<String> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, builder.ToString());
return *result;
}
template <typename ResultSeqString>
-MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithEmptyString(
+MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString(
Isolate* isolate,
Handle<String> subject,
Handle<JSRegExp> regexp,
@@ -4163,11 +4217,11 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithEmptyString(
}
RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
- if (global_cache.HasException()) return Failure::Exception();
+ if (global_cache.HasException()) return isolate->heap()->exception();
int32_t* current_match = global_cache.FetchNext();
if (current_match == NULL) {
- if (global_cache.HasException()) return Failure::Exception();
+ if (global_cache.HasException()) return isolate->heap()->exception();
return *subject;
}
@@ -4182,12 +4236,11 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithEmptyString(
Handle<ResultSeqString> answer;
if (ResultSeqString::kHasAsciiEncoding) {
answer = Handle<ResultSeqString>::cast(
- isolate->factory()->NewRawOneByteString(new_length));
+ isolate->factory()->NewRawOneByteString(new_length).ToHandleChecked());
} else {
answer = Handle<ResultSeqString>::cast(
- isolate->factory()->NewRawTwoByteString(new_length));
+ isolate->factory()->NewRawTwoByteString(new_length).ToHandleChecked());
}
- ASSERT(!answer.is_null());
int prev = 0;
int position = 0;
@@ -4205,7 +4258,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithEmptyString(
current_match = global_cache.FetchNext();
} while (current_match != NULL);
- if (global_cache.HasException()) return Failure::Exception();
+ if (global_cache.HasException()) return isolate->heap()->exception();
RegExpImpl::SetLastMatchInfo(last_match_info,
subject,
@@ -4231,13 +4284,18 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithEmptyString(
Address end_of_string = answer->address() + string_size;
Heap* heap = isolate->heap();
+
+ // The trimming is performed on a newly allocated object, which is on a
+ // fresly allocated page or on an already swept page. Hence, the sweeper
+ // thread can not get confused with the filler creation. No synchronization
+ // needed.
heap->CreateFillerObjectAt(end_of_string, delta);
heap->AdjustLiveBytes(answer->address(), -delta, Heap::FROM_MUTATOR);
return *answer;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceGlobalRegExpWithString) {
+RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
@@ -4246,9 +4304,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceGlobalRegExpWithString) {
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
- ASSERT(regexp->GetFlags().is_global());
+ RUNTIME_ASSERT(regexp->GetFlags().is_global());
- if (!subject->IsFlat()) subject = FlattenGetString(subject);
+ subject = String::Flatten(subject);
if (replacement->length() == 0) {
if (subject->HasOnlyOneByteChars()) {
@@ -4260,42 +4318,41 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceGlobalRegExpWithString) {
}
}
- if (!replacement->IsFlat()) replacement = FlattenGetString(replacement);
+ replacement = String::Flatten(replacement);
return StringReplaceGlobalRegExpWithString(
isolate, subject, regexp, replacement, last_match_info);
}
-Handle<String> StringReplaceOneCharWithString(Isolate* isolate,
- Handle<String> subject,
- Handle<String> search,
- Handle<String> replace,
- bool* found,
- int recursion_limit) {
- if (recursion_limit == 0) return Handle<String>::null();
+// This may return an empty MaybeHandle if an exception is thrown or
+// we abort due to reaching the recursion limit.
+MaybeHandle<String> StringReplaceOneCharWithString(Isolate* isolate,
+ Handle<String> subject,
+ Handle<String> search,
+ Handle<String> replace,
+ bool* found,
+ int recursion_limit) {
+ if (recursion_limit == 0) return MaybeHandle<String>();
+ recursion_limit--;
if (subject->IsConsString()) {
ConsString* cons = ConsString::cast(*subject);
Handle<String> first = Handle<String>(cons->first());
Handle<String> second = Handle<String>(cons->second());
- Handle<String> new_first =
- StringReplaceOneCharWithString(isolate,
- first,
- search,
- replace,
- found,
- recursion_limit - 1);
- if (new_first.is_null()) return new_first;
+ Handle<String> new_first;
+ if (!StringReplaceOneCharWithString(
+ isolate, first, search, replace, found, recursion_limit)
+ .ToHandle(&new_first)) {
+ return MaybeHandle<String>();
+ }
if (*found) return isolate->factory()->NewConsString(new_first, second);
- Handle<String> new_second =
- StringReplaceOneCharWithString(isolate,
- second,
- search,
- replace,
- found,
- recursion_limit - 1);
- if (new_second.is_null()) return new_second;
+ Handle<String> new_second;
+ if (!StringReplaceOneCharWithString(
+ isolate, second, search, replace, found, recursion_limit)
+ .ToHandle(&new_second)) {
+ return MaybeHandle<String>();
+ }
if (*found) return isolate->factory()->NewConsString(first, new_second);
return subject;
@@ -4304,8 +4361,11 @@ Handle<String> StringReplaceOneCharWithString(Isolate* isolate,
if (index == -1) return subject;
*found = true;
Handle<String> first = isolate->factory()->NewSubString(subject, 0, index);
- Handle<String> cons1 = isolate->factory()->NewConsString(first, replace);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, cons1, Handle<String>());
+ Handle<String> cons1;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, cons1,
+ isolate->factory()->NewConsString(first, replace),
+ String);
Handle<String> second =
isolate->factory()->NewSubString(subject, index + 1, subject->length());
return isolate->factory()->NewConsString(cons1, second);
@@ -4313,7 +4373,7 @@ Handle<String> StringReplaceOneCharWithString(Isolate* isolate,
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceOneCharWithString) {
+RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
@@ -4324,20 +4384,20 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceOneCharWithString) {
// retry with a flattened subject string.
const int kRecursionLimit = 0x1000;
bool found = false;
- Handle<String> result = StringReplaceOneCharWithString(isolate,
- subject,
- search,
- replace,
- &found,
- kRecursionLimit);
- if (!result.is_null()) return *result;
- if (isolate->has_pending_exception()) return Failure::Exception();
- return *StringReplaceOneCharWithString(isolate,
- FlattenGetString(subject),
- search,
- replace,
- &found,
- kRecursionLimit);
+ Handle<String> result;
+ if (StringReplaceOneCharWithString(
+ isolate, subject, search, replace, &found, kRecursionLimit)
+ .ToHandle(&result)) {
+ return *result;
+ }
+ if (isolate->has_pending_exception()) return isolate->heap()->exception();
+
+ subject = String::Flatten(subject);
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ StringReplaceOneCharWithString(
+ isolate, subject, search, replace, &found, kRecursionLimit));
+ return *result;
}
@@ -4357,8 +4417,8 @@ int Runtime::StringMatch(Isolate* isolate,
int subject_length = sub->length();
if (start_index + pattern_length > subject_length) return -1;
- if (!sub->IsFlat()) FlattenString(sub);
- if (!pat->IsFlat()) FlattenString(pat);
+ sub = String::Flatten(sub);
+ pat = String::Flatten(pat);
DisallowHeapAllocation no_gc; // ensure vectors stay valid
// Extract flattened substrings of cons strings before determining asciiness.
@@ -4393,20 +4453,19 @@ int Runtime::StringMatch(Isolate* isolate,
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringIndexOf) {
+RUNTIME_FUNCTION(Runtime_StringIndexOf) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
- Object* index = args[2];
uint32_t start_index;
if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length()));
- int position =
- Runtime::StringMatch(isolate, sub, pat, start_index);
+ int position = Runtime::StringMatch(isolate, sub, pat, start_index);
return Smi::FromInt(position);
}
@@ -4446,14 +4505,14 @@ static int StringMatchBackwards(Vector<const schar> subject,
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLastIndexOf) {
+RUNTIME_FUNCTION(Runtime_StringLastIndexOf) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
- Object* index = args[2];
uint32_t start_index;
if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
@@ -4468,8 +4527,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLastIndexOf) {
return Smi::FromInt(start_index);
}
- if (!sub->IsFlat()) FlattenString(sub);
- if (!pat->IsFlat()) FlattenString(pat);
+ sub = String::Flatten(sub);
+ pat = String::Flatten(pat);
int position = -1;
DisallowHeapAllocation no_gc; // ensure vectors stay valid
@@ -4505,14 +4564,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLastIndexOf) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLocaleCompare) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_StringLocaleCompare) {
+ HandleScope handle_scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(String, str1, 0);
- CONVERT_ARG_CHECKED(String, str2, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
- if (str1 == str2) return Smi::FromInt(0); // Equal.
+ if (str1.is_identical_to(str2)) return Smi::FromInt(0); // Equal.
int str1_length = str1->length();
int str2_length = str2->length();
@@ -4532,28 +4591,24 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLocaleCompare) {
int d = str1->Get(0) - str2->Get(0);
if (d != 0) return Smi::FromInt(d);
- str1->TryFlatten();
- str2->TryFlatten();
+ str1 = String::Flatten(str1);
+ str2 = String::Flatten(str2);
- ConsStringIteratorOp* op1 =
- isolate->runtime_state()->string_locale_compare_it1();
- ConsStringIteratorOp* op2 =
- isolate->runtime_state()->string_locale_compare_it2();
- // TODO(dcarney) Can do array compares here more efficiently.
- StringCharacterStream stream1(str1, op1);
- StringCharacterStream stream2(str2, op2);
+ DisallowHeapAllocation no_gc;
+ String::FlatContent flat1 = str1->GetFlatContent();
+ String::FlatContent flat2 = str2->GetFlatContent();
for (int i = 0; i < end; i++) {
- uint16_t char1 = stream1.GetNext();
- uint16_t char2 = stream2.GetNext();
- if (char1 != char2) return Smi::FromInt(char1 - char2);
+ if (flat1.Get(i) != flat2.Get(i)) {
+ return Smi::FromInt(flat1.Get(i) - flat2.Get(i));
+ }
}
return Smi::FromInt(str1_length - str2_length);
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_SubString) {
+RUNTIME_FUNCTION(RuntimeHidden_SubString) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
@@ -4581,16 +4636,18 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_SubString) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
+RUNTIME_FUNCTION(Runtime_StringMatch) {
HandleScope handles(isolate);
- ASSERT_EQ(3, args.length());
+ ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
+ RUNTIME_ASSERT(regexp_info->HasFastObjectElements());
+
RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
- if (global_cache.HasException()) return Failure::Exception();
+ if (global_cache.HasException()) return isolate->heap()->exception();
int capture_count = regexp->CaptureCount();
@@ -4604,7 +4661,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
offsets.Add(match[1], zone_scope.zone()); // end
}
- if (global_cache.HasException()) return Failure::Exception();
+ if (global_cache.HasException()) return isolate->heap()->exception();
if (offsets.length() == 0) {
// Not a single match.
@@ -4638,7 +4695,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
// Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
// separate last match info. See comment on that function.
template<bool has_capture>
-static MaybeObject* SearchRegExpMultiple(
+static Object* SearchRegExpMultiple(
Isolate* isolate,
Handle<String> subject,
Handle<JSRegExp> regexp,
@@ -4676,7 +4733,7 @@ static MaybeObject* SearchRegExpMultiple(
}
RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
- if (global_cache.HasException()) return Failure::Exception();
+ if (global_cache.HasException()) return isolate->heap()->exception();
Handle<FixedArray> result_elements;
if (result_array->HasFastObjectElements()) {
@@ -4752,7 +4809,7 @@ static MaybeObject* SearchRegExpMultiple(
}
}
- if (global_cache.HasException()) return Failure::Exception();
+ if (global_cache.HasException()) return isolate->heap()->exception();
if (match_start >= 0) {
// Finished matching, with at least one match.
@@ -4773,10 +4830,10 @@ static MaybeObject* SearchRegExpMultiple(
fixed_array->set(fixed_array->length() - 1,
Smi::FromInt(builder.length()));
// Cache the result and turn the FixedArray into a COW array.
- RegExpResultsCache::Enter(isolate->heap(),
- *subject,
- regexp->data(),
- *fixed_array,
+ RegExpResultsCache::Enter(isolate,
+ subject,
+ handle(regexp->data(), isolate),
+ fixed_array,
RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
}
return *builder.ToJSArray(result_array);
@@ -4789,16 +4846,16 @@ static MaybeObject* SearchRegExpMultiple(
// This is only called for StringReplaceGlobalRegExpWithFunction. This sets
// lastMatchInfoOverride to maintain the last match info, so we don't need to
// set any other last match array info.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
+RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) {
HandleScope handles(isolate);
ASSERT(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
- if (!subject->IsFlat()) FlattenString(subject);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
+ subject = String::Flatten(subject);
ASSERT(regexp->GetFlags().is_global());
if (regexp->CaptureCount() == 0) {
@@ -4811,8 +4868,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberToRadixString) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(radix, 1);
RUNTIME_ASSERT(2 <= radix && radix <= 36);
@@ -4823,7 +4880,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
if (value >= 0 && value < radix) {
// Character array used for conversion.
static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
- return isolate->heap()->
+ return *isolate->factory()->
LookupSingleCharacterStringFromCode(kCharTable[value]);
}
}
@@ -4831,40 +4888,39 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
// Slow case.
CONVERT_DOUBLE_ARG_CHECKED(value, 0);
if (std::isnan(value)) {
- return *isolate->factory()->nan_string();
+ return isolate->heap()->nan_string();
}
if (std::isinf(value)) {
if (value < 0) {
- return *isolate->factory()->minus_infinity_string();
+ return isolate->heap()->minus_infinity_string();
}
- return *isolate->factory()->infinity_string();
+ return isolate->heap()->infinity_string();
}
char* str = DoubleToRadixCString(value, radix);
- MaybeObject* result =
- isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
+ Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
DeleteArray(str);
- return result;
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberToFixed) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(value, 0);
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
int f = FastD2IChecked(f_number);
- RUNTIME_ASSERT(f >= 0);
+ // See DoubleToFixedCString for these constants:
+ RUNTIME_ASSERT(f >= 0 && f <= 20);
char* str = DoubleToFixedCString(value, f);
- MaybeObject* res =
- isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
+ Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
DeleteArray(str);
- return res;
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberToExponential) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(value, 0);
@@ -4872,15 +4928,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
int f = FastD2IChecked(f_number);
RUNTIME_ASSERT(f >= -1 && f <= 20);
char* str = DoubleToExponentialCString(value, f);
- MaybeObject* res =
- isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
+ Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
DeleteArray(str);
- return res;
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberToPrecision) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(value, 0);
@@ -4888,23 +4943,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
int f = FastD2IChecked(f_number);
RUNTIME_ASSERT(f >= 1 && f <= 21);
char* str = DoubleToPrecisionCString(value, f);
- MaybeObject* res =
- isolate->heap()->AllocateStringFromOneByte(CStrVector(str));
+ Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
DeleteArray(str);
- return res;
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsValidSmi) {
- HandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_IsValidSmi) {
+ SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
- if (Smi::IsValid(number)) {
- return isolate->heap()->true_value();
- } else {
- return isolate->heap()->false_value();
- }
+ return isolate->heap()->ToBoolean(Smi::IsValid(number));
}
@@ -4912,18 +4962,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsValidSmi) {
// string->Get(index).
static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
if (index < static_cast<uint32_t>(string->length())) {
- string->TryFlatten();
- return LookupSingleCharacterStringFromCode(
- string->GetIsolate(),
- string->Get(index));
+ Factory* factory = string->GetIsolate()->factory();
+ return factory->LookupSingleCharacterStringFromCode(
+ String::Flatten(string)->Get(index));
}
return Execution::CharAt(string, index);
}
-Handle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
- Handle<Object> object,
- uint32_t index) {
+MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
+ Handle<Object> object,
+ uint32_t index) {
// Handle [] indexing on Strings
if (object->IsString()) {
Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
@@ -4948,98 +4997,88 @@ Handle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
}
-static Handle<Name> ToName(Isolate* isolate, Handle<Object> key) {
+MUST_USE_RESULT
+static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) {
if (key->IsName()) {
return Handle<Name>::cast(key);
} else {
- bool has_pending_exception = false;
- Handle<Object> converted =
- Execution::ToString(isolate, key, &has_pending_exception);
- if (has_pending_exception) return Handle<Name>();
+ Handle<Object> converted;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, converted, Execution::ToString(isolate, key), Name);
return Handle<Name>::cast(converted);
}
}
-MaybeObject* Runtime::HasObjectProperty(Isolate* isolate,
- Handle<JSReceiver> object,
- Handle<Object> key) {
- HandleScope scope(isolate);
-
+MaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate,
+ Handle<JSReceiver> object,
+ Handle<Object> key) {
// Check if the given key is an array index.
uint32_t index;
if (key->ToArrayIndex(&index)) {
- return isolate->heap()->ToBoolean(JSReceiver::HasElement(object, index));
+ return isolate->factory()->ToBoolean(JSReceiver::HasElement(object, index));
}
// Convert the key to a name - possibly by calling back into JavaScript.
- Handle<Name> name = ToName(isolate, key);
- RETURN_IF_EMPTY_HANDLE(isolate, name);
-
- return isolate->heap()->ToBoolean(JSReceiver::HasProperty(object, name));
-}
+ Handle<Name> name;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
-MaybeObject* Runtime::GetObjectPropertyOrFail(
- Isolate* isolate,
- Handle<Object> object,
- Handle<Object> key) {
- CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate,
- GetObjectProperty(isolate, object, key));
+ return isolate->factory()->ToBoolean(JSReceiver::HasProperty(object, name));
}
-MaybeObject* Runtime::GetObjectProperty(Isolate* isolate,
- Handle<Object> object,
- Handle<Object> key) {
- HandleScope scope(isolate);
+MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
+ Handle<Object> object,
+ Handle<Object> key) {
if (object->IsUndefined() || object->IsNull()) {
Handle<Object> args[2] = { key, object };
- Handle<Object> error =
+ return isolate->Throw<Object>(
isolate->factory()->NewTypeError("non_object_property_load",
- HandleVector(args, 2));
- return isolate->Throw(*error);
+ HandleVector(args, 2)));
}
// Check if the given key is an array index.
uint32_t index;
if (key->ToArrayIndex(&index)) {
- Handle<Object> result = GetElementOrCharAt(isolate, object, index);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
- return *result;
+ return GetElementOrCharAt(isolate, object, index);
}
// Convert the key to a name - possibly by calling back into JavaScript.
- Handle<Name> name = ToName(isolate, key);
- RETURN_IF_EMPTY_HANDLE(isolate, name);
+ Handle<Name> name;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
// Check if the name is trivially convertible to an index and get
// the element if so.
if (name->AsArrayIndex(&index)) {
- Handle<Object> result = GetElementOrCharAt(isolate, object, index);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
- return *result;
+ return GetElementOrCharAt(isolate, object, index);
} else {
- return object->GetProperty(*name);
+ return Object::GetProperty(object, name);
}
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetProperty) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_GetProperty) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
- Handle<Object> object = args.at<Object>(0);
- Handle<Object> key = args.at<Object>(1);
-
- return Runtime::GetObjectProperty(isolate, object, key);
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Runtime::GetObjectProperty(isolate, object, key));
+ return *result;
}
// KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
+
// Fast cases for getting named properties of the receiver JSObject
// itself.
//
@@ -5051,15 +5090,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
//
// Additionally, we need to make sure that we do not cache results
// for objects that require access checks.
- if (args[0]->IsJSObject()) {
- if (!args[0]->IsJSGlobalProxy() &&
- !args[0]->IsAccessCheckNeeded() &&
- args[1]->IsName()) {
- JSObject* receiver = JSObject::cast(args[0]);
- Name* key = Name::cast(args[1]);
+ if (receiver_obj->IsJSObject()) {
+ if (!receiver_obj->IsJSGlobalProxy() &&
+ !receiver_obj->IsAccessCheckNeeded() &&
+ key_obj->IsName()) {
+ DisallowHeapAllocation no_allocation;
+ Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
+ Handle<Name> key = Handle<Name>::cast(key_obj);
if (receiver->HasFastProperties()) {
// Attempt to use lookup cache.
- Map* receiver_map = receiver->map();
+ Handle<Map> receiver_map(receiver->map(), isolate);
KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
int offset = keyed_lookup_cache->Lookup(receiver_map, key);
if (offset != -1) {
@@ -5080,7 +5120,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
if (!result.representation().IsDouble()) {
keyed_lookup_cache->Update(receiver_map, key, offset);
}
- return receiver->FastPropertyAt(result.representation(), offset);
+ AllowHeapAllocation allow_allocation;
+ return *JSObject::FastPropertyAt(
+ receiver, result.representation(), offset);
}
} else {
// Attempt dictionary lookup.
@@ -5095,48 +5137,46 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
// If value is the hole do the general lookup.
}
}
- } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) {
+ } else if (FLAG_smi_only_arrays && key_obj->IsSmi()) {
// JSObject without a name key. If the key is a Smi, check for a
// definite out-of-bounds access to elements, which is a strong indicator
// that subsequent accesses will also call the runtime. Proactively
// transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
// doubles for those future calls in the case that the elements would
// become FAST_DOUBLE_ELEMENTS.
- Handle<JSObject> js_object(args.at<JSObject>(0));
+ Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
ElementsKind elements_kind = js_object->GetElementsKind();
if (IsFastDoubleElementsKind(elements_kind)) {
- FixedArrayBase* elements = js_object->elements();
- if (args.at<Smi>(1)->value() >= elements->length()) {
+ Handle<Smi> key = Handle<Smi>::cast(key_obj);
+ if (key->value() >= js_object->elements()->length()) {
if (IsFastHoleyElementsKind(elements_kind)) {
elements_kind = FAST_HOLEY_ELEMENTS;
} else {
elements_kind = FAST_ELEMENTS;
}
- MaybeObject* maybe_object = TransitionElements(js_object,
- elements_kind,
- isolate);
- if (maybe_object->IsFailure()) return maybe_object;
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, TransitionElements(js_object, elements_kind, isolate));
}
} else {
ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
!IsFastElementsKind(elements_kind));
}
}
- } else if (args[0]->IsString() && args[1]->IsSmi()) {
+ } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
// Fast case for string indexing using [] with a smi index.
- HandleScope scope(isolate);
- Handle<String> str = args.at<String>(0);
+ Handle<String> str = Handle<String>::cast(receiver_obj);
int index = args.smi_at(1);
if (index >= 0 && index < str->length()) {
- Handle<Object> result = GetCharAt(str, index);
- return *result;
+ return *GetCharAt(str, index);
}
}
// Fall back to GetObjectProperty.
- return Runtime::GetObjectProperty(isolate,
- args.at<Object>(0),
- args.at<Object>(1));
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
+ return *result;
}
@@ -5151,7 +5191,7 @@ static bool IsValidAccessor(Handle<Object> obj) {
// Steps 9c & 12 - replace an existing data property with an accessor property.
// Step 12 - update an existing accessor property with an accessor or generic
// descriptor.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) {
+RUNTIME_FUNCTION(Runtime_DefineOrRedefineAccessorProperty) {
HandleScope scope(isolate);
ASSERT(args.length() == 5);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
@@ -5166,8 +5206,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) {
PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
bool fast = obj->HasFastProperties();
+ // DefineAccessor checks access rights.
JSObject::DefineAccessor(obj, name, getter, setter, attr);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
if (fast) JSObject::TransformToFastProperties(obj, 0);
return isolate->heap()->undefined_value();
}
@@ -5179,7 +5220,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) {
// Steps 9b & 12 - replace an existing accessor property with a data property.
// Step 12 - update an existing data property with a data or generic
// descriptor.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
+RUNTIME_FUNCTION(Runtime_DefineOrRedefineDataProperty) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
@@ -5189,31 +5230,34 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
+ // Check access rights if needed.
+ if (js_object->IsAccessCheckNeeded() &&
+ !isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) {
+ return isolate->heap()->undefined_value();
+ }
+
LookupResult lookup(isolate);
- js_object->LocalLookupRealNamedProperty(*name, &lookup);
+ js_object->LocalLookupRealNamedProperty(name, &lookup);
// Special case for callback properties.
if (lookup.IsPropertyCallbacks()) {
Handle<Object> callback(lookup.GetCallbackObject(), isolate);
- // To be compatible with Safari we do not change the value on API objects
- // in Object.defineProperty(). Firefox disagrees here, and actually changes
- // the value.
- if (callback->IsAccessorInfo()) {
- return isolate->heap()->undefined_value();
- }
- // Avoid redefining foreign callback as data property, just use the stored
+ // Avoid redefining callback as data property, just use the stored
// setter to update the value instead.
// TODO(mstarzinger): So far this only works if property attributes don't
// change, this should be fixed once we cleanup the underlying code.
- if (callback->IsForeign() && lookup.GetAttributes() == attr) {
- Handle<Object> result_object =
+ ASSERT(!callback->IsForeign());
+ if (callback->IsAccessorInfo() &&
+ lookup.GetAttributes() == attr) {
+ Handle<Object> result_object;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result_object,
JSObject::SetPropertyWithCallback(js_object,
callback,
name,
obj_value,
handle(lookup.holder()),
- STRICT);
- RETURN_IF_EMPTY_HANDLE(isolate, result_object);
+ STRICT));
return *result_object;
}
}
@@ -5235,57 +5279,40 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
// Use IgnoreAttributes version since a readonly property may be
// overridden and SetProperty does not allow this.
- Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
- js_object, name, obj_value, attr);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ js_object, name, obj_value, attr));
return *result;
}
- Handle<Object> result = Runtime::ForceSetObjectProperty(isolate, js_object,
- name,
- obj_value,
- attr);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Runtime::ForceSetObjectProperty(
+ js_object, name, obj_value, attr,
+ JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED));
return *result;
}
// Return property without being observable by accessors or interceptors.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_GetDataProperty) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
- LookupResult lookup(isolate);
- object->LookupRealNamedProperty(*key, &lookup);
- if (!lookup.IsFound()) return isolate->heap()->undefined_value();
- switch (lookup.type()) {
- case NORMAL:
- return lookup.holder()->GetNormalizedProperty(&lookup);
- case FIELD:
- return lookup.holder()->FastPropertyAt(
- lookup.representation(),
- lookup.GetFieldIndex().field_index());
- case CONSTANT:
- return lookup.GetConstant();
- case CALLBACKS:
- case HANDLER:
- case INTERCEPTOR:
- case TRANSITION:
- return isolate->heap()->undefined_value();
- case NONEXISTENT:
- UNREACHABLE();
- }
- return isolate->heap()->undefined_value();
+ return *JSObject::GetDataProperty(object, key);
}
-Handle<Object> Runtime::SetObjectProperty(Isolate* isolate,
- Handle<Object> object,
- Handle<Object> key,
- Handle<Object> value,
- PropertyAttributes attr,
- StrictMode strict_mode) {
+MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
+ Handle<Object> object,
+ Handle<Object> key,
+ Handle<Object> value,
+ PropertyAttributes attr,
+ StrictMode strict_mode) {
SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY;
if (object->IsUndefined() || object->IsNull()) {
@@ -5293,15 +5320,17 @@ Handle<Object> Runtime::SetObjectProperty(Isolate* isolate,
Handle<Object> error =
isolate->factory()->NewTypeError("non_object_property_store",
HandleVector(args, 2));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
if (object->IsJSProxy()) {
- bool has_pending_exception = false;
- Handle<Object> name_object = key->IsSymbol()
- ? key : Execution::ToString(isolate, key, &has_pending_exception);
- if (has_pending_exception) return Handle<Object>(); // exception
+ Handle<Object> name_object;
+ if (key->IsSymbol()) {
+ name_object = key;
+ } else {
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, name_object, Execution::ToString(isolate, key), Object);
+ }
Handle<Name> name = Handle<Name>::cast(name_object);
return JSReceiver::SetProperty(Handle<JSProxy>::cast(object), name, value,
attr,
@@ -5327,22 +5356,19 @@ Handle<Object> Runtime::SetObjectProperty(Isolate* isolate,
return value;
}
- js_object->ValidateElements();
+ JSObject::ValidateElements(js_object);
if (js_object->HasExternalArrayElements() ||
js_object->HasFixedTypedArrayElements()) {
if (!value->IsNumber() && !value->IsUndefined()) {
- bool has_exception;
- Handle<Object> number =
- Execution::ToNumber(isolate, value, &has_exception);
- if (has_exception) return Handle<Object>(); // exception
- value = number;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, value, Execution::ToNumber(isolate, value), Object);
}
}
- Handle<Object> result = JSObject::SetElement(js_object, index, value, attr,
- strict_mode,
- true,
- set_mode);
- js_object->ValidateElements();
+
+ MaybeHandle<Object> result = JSObject::SetElement(
+ js_object, index, value, attr, strict_mode, true, set_mode);
+ JSObject::ValidateElements(js_object);
+
return result.is_null() ? result : value;
}
@@ -5351,44 +5377,40 @@ Handle<Object> Runtime::SetObjectProperty(Isolate* isolate,
if (name->AsArrayIndex(&index)) {
if (js_object->HasExternalArrayElements()) {
if (!value->IsNumber() && !value->IsUndefined()) {
- bool has_exception;
- Handle<Object> number =
- Execution::ToNumber(isolate, value, &has_exception);
- if (has_exception) return Handle<Object>(); // exception
- value = number;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, value, Execution::ToNumber(isolate, value), Object);
}
}
- return JSObject::SetElement(js_object, index, value, attr, strict_mode,
- true,
- set_mode);
+ return JSObject::SetElement(js_object, index, value, attr,
+ strict_mode, true, set_mode);
} else {
- if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
+ if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
}
}
// Call-back into JavaScript to convert the key to a string.
- bool has_pending_exception = false;
- Handle<Object> converted =
- Execution::ToString(isolate, key, &has_pending_exception);
- if (has_pending_exception) return Handle<Object>(); // exception
+ Handle<Object> converted;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, converted, Execution::ToString(isolate, key), Object);
Handle<String> name = Handle<String>::cast(converted);
if (name->AsArrayIndex(&index)) {
- return JSObject::SetElement(js_object, index, value, attr, strict_mode,
- true,
- set_mode);
+ return JSObject::SetElement(js_object, index, value, attr,
+ strict_mode, true, set_mode);
} else {
return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
}
}
-Handle<Object> Runtime::ForceSetObjectProperty(Isolate* isolate,
- Handle<JSObject> js_object,
- Handle<Object> key,
- Handle<Object> value,
- PropertyAttributes attr) {
+MaybeHandle<Object> Runtime::ForceSetObjectProperty(
+ Handle<JSObject> js_object,
+ Handle<Object> key,
+ Handle<Object> value,
+ PropertyAttributes attr,
+ JSReceiver::StoreFromKeyed store_from_keyed) {
+ Isolate* isolate = js_object->GetIsolate();
// Check if the given key is an array index.
uint32_t index;
if (key->ToArrayIndex(&index)) {
@@ -5403,48 +5425,46 @@ Handle<Object> Runtime::ForceSetObjectProperty(Isolate* isolate,
return value;
}
- return JSObject::SetElement(js_object, index, value, attr, SLOPPY,
- false,
- DEFINE_PROPERTY);
+ return JSObject::SetElement(js_object, index, value, attr,
+ SLOPPY, false, DEFINE_PROPERTY);
}
if (key->IsName()) {
Handle<Name> name = Handle<Name>::cast(key);
if (name->AsArrayIndex(&index)) {
- return JSObject::SetElement(js_object, index, value, attr, SLOPPY,
- false,
- DEFINE_PROPERTY);
+ return JSObject::SetElement(js_object, index, value, attr,
+ SLOPPY, false, DEFINE_PROPERTY);
} else {
- if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
- return JSObject::SetLocalPropertyIgnoreAttributes(js_object, name,
- value, attr);
+ if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
+ return JSObject::SetLocalPropertyIgnoreAttributes(
+ js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
+ ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
+ store_from_keyed);
}
}
// Call-back into JavaScript to convert the key to a string.
- bool has_pending_exception = false;
- Handle<Object> converted =
- Execution::ToString(isolate, key, &has_pending_exception);
- if (has_pending_exception) return Handle<Object>(); // exception
+ Handle<Object> converted;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, converted, Execution::ToString(isolate, key), Object);
Handle<String> name = Handle<String>::cast(converted);
if (name->AsArrayIndex(&index)) {
- return JSObject::SetElement(js_object, index, value, attr, SLOPPY,
- false,
- DEFINE_PROPERTY);
+ return JSObject::SetElement(js_object, index, value, attr,
+ SLOPPY, false, DEFINE_PROPERTY);
} else {
- return JSObject::SetLocalPropertyIgnoreAttributes(js_object, name, value,
- attr);
+ return JSObject::SetLocalPropertyIgnoreAttributes(
+ js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
+ ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
+ store_from_keyed);
}
}
-MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate,
- Handle<JSReceiver> receiver,
- Handle<Object> key,
- JSReceiver::DeleteMode mode) {
- HandleScope scope(isolate);
-
+MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate,
+ Handle<JSReceiver> receiver,
+ Handle<Object> key,
+ JSReceiver::DeleteMode mode) {
// Check if the given key is an array index.
uint32_t index;
if (key->ToArrayIndex(&index)) {
@@ -5455,12 +5475,10 @@ MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate,
// underlying string does nothing with the deletion, we can ignore
// such deletions.
if (receiver->IsStringObjectWithCharacterAt(index)) {
- return isolate->heap()->true_value();
+ return isolate->factory()->true_value();
}
- Handle<Object> result = JSReceiver::DeleteElement(receiver, index, mode);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
- return *result;
+ return JSReceiver::DeleteElement(receiver, index, mode);
}
Handle<Name> name;
@@ -5468,21 +5486,18 @@ MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate,
name = Handle<Name>::cast(key);
} else {
// Call-back into JavaScript to convert the key to a string.
- bool has_pending_exception = false;
- Handle<Object> converted = Execution::ToString(
- isolate, key, &has_pending_exception);
- if (has_pending_exception) return Failure::Exception();
+ Handle<Object> converted;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, converted, Execution::ToString(isolate, key), Object);
name = Handle<String>::cast(converted);
}
- if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
- Handle<Object> result = JSReceiver::DeleteProperty(receiver, name, mode);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
- return *result;
+ if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
+ return JSReceiver::DeleteProperty(receiver, name, mode);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetHiddenProperty) {
+RUNTIME_FUNCTION(Runtime_SetHiddenProperty) {
HandleScope scope(isolate);
RUNTIME_ASSERT(args.length() == 3);
@@ -5493,7 +5508,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetHiddenProperty) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
+RUNTIME_FUNCTION(Runtime_SetProperty) {
HandleScope scope(isolate);
RUNTIME_ASSERT(args.length() == 4 || args.length() == 5);
@@ -5513,16 +5528,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
strict_mode = strict_mode_arg;
}
- Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key,
- value,
- attributes,
- strict_mode);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Runtime::SetObjectProperty(
+ isolate, object, key, value, attributes, strict_mode));
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsKind) {
+RUNTIME_FUNCTION(Runtime_TransitionElementsKind) {
HandleScope scope(isolate);
RUNTIME_ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
@@ -5535,7 +5550,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsKind) {
// Set the native flag on the function.
// This is used to decide if we should transform null and undefined
// into the global object when doing call and apply.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
+RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
SealHandleScope shs(isolate);
RUNTIME_ASSERT(args.length() == 1);
@@ -5549,11 +5564,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInlineBuiltinFlag) {
+RUNTIME_FUNCTION(Runtime_SetInlineBuiltinFlag) {
SealHandleScope shs(isolate);
RUNTIME_ASSERT(args.length() == 1);
-
- Handle<Object> object = args.at<Object>(0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
if (object->IsJSFunction()) {
JSFunction* func = JSFunction::cast(*object);
@@ -5563,12 +5577,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInlineBuiltinFlag) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) {
+RUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) {
HandleScope scope(isolate);
RUNTIME_ASSERT(args.length() == 5);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_SMI_ARG_CHECKED(store_index, 1);
- Handle<Object> value = args.at<Object>(2);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
CONVERT_SMI_ARG_CHECKED(literal_index, 4);
@@ -5622,29 +5636,22 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) {
// Check whether debugger and is about to step into the callback that is passed
// to a built-in function such as Array.forEach.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugCallbackSupportsStepping) {
- SealHandleScope shs(isolate);
-#ifdef ENABLE_DEBUGGER_SUPPORT
+RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) {
+ ASSERT(args.length() == 1);
if (!isolate->IsDebuggerActive() || !isolate->debug()->StepInActive()) {
return isolate->heap()->false_value();
}
CONVERT_ARG_CHECKED(Object, callback, 0);
// We do not step into the callback if it's a builtin or not even a function.
- if (!callback->IsJSFunction() || JSFunction::cast(callback)->IsBuiltin()) {
- return isolate->heap()->false_value();
- }
- return isolate->heap()->true_value();
-#else
- return isolate->heap()->false_value();
-#endif // ENABLE_DEBUGGER_SUPPORT
+ return isolate->heap()->ToBoolean(
+ callback->IsJSFunction() && !JSFunction::cast(callback)->IsBuiltin());
}
// Set one shot breakpoints for the callback function that is passed to a
// built-in function such as Array.forEach to enable stepping into the callback.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrepareStepInIfStepping) {
- SealHandleScope shs(isolate);
-#ifdef ENABLE_DEBUGGER_SUPPORT
+RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
+ ASSERT(args.length() == 1);
Debug* debug = isolate->debug();
if (!debug->IsStepping()) return isolate->heap()->undefined_value();
CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 0);
@@ -5654,14 +5661,33 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrepareStepInIfStepping) {
// again, we need to clear the step out at this point.
debug->ClearStepOut();
debug->FloodWithOneShot(callback);
-#endif // ENABLE_DEBUGGER_SUPPORT
+ return isolate->heap()->undefined_value();
+}
+
+
+// The argument is a closure that is kept until the epilogue is called.
+// On exception, the closure is called, which returns the promise if the
+// exception is considered uncaught, or undefined otherwise.
+RUNTIME_FUNCTION(Runtime_DebugPromiseHandlePrologue) {
+ ASSERT(args.length() == 1);
+ HandleScope scope(isolate);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, promise_getter, 0);
+ isolate->debug()->PromiseHandlePrologue(promise_getter);
+ return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugPromiseHandleEpilogue) {
+ ASSERT(args.length() == 0);
+ SealHandleScope shs(isolate);
+ isolate->debug()->PromiseHandleEpilogue();
return isolate->heap()->undefined_value();
}
// Set a local property, even if it is READ_ONLY. If the property does not
// exist, it will be added with attributes NONE.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) {
+RUNTIME_FUNCTION(Runtime_IgnoreAttributesAndSetProperty) {
HandleScope scope(isolate);
RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
@@ -5676,14 +5702,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) {
(unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
attributes = static_cast<PropertyAttributes>(unchecked_value);
}
- Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
- object, name, value, attributes);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ object, name, value, attributes));
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) {
+RUNTIME_FUNCTION(Runtime_DeleteProperty) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
@@ -5691,15 +5719,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) {
CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
JSReceiver::DeleteMode delete_mode = strict_mode == STRICT
? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION;
- Handle<Object> result = JSReceiver::DeleteProperty(object, key, delete_mode);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ JSReceiver::DeleteProperty(object, key, delete_mode));
return *result;
}
-static MaybeObject* HasLocalPropertyImplementation(Isolate* isolate,
- Handle<JSObject> object,
- Handle<Name> key) {
+static Object* HasLocalPropertyImplementation(Isolate* isolate,
+ Handle<JSObject> object,
+ Handle<Name> key) {
if (JSReceiver::HasLocalProperty(object, key)) {
return isolate->heap()->true_value();
}
@@ -5713,16 +5743,16 @@ static MaybeObject* HasLocalPropertyImplementation(Isolate* isolate,
Handle<JSObject>::cast(proto),
key);
}
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->false_value();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) {
+RUNTIME_FUNCTION(Runtime_HasLocalProperty) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
- Handle<Object> object = args.at<Object>(0);
uint32_t index;
const bool key_is_array_index = key->AsArrayIndex(&index);
@@ -5737,7 +5767,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) {
ASSERT(!isolate->has_scheduled_exception());
return isolate->heap()->true_value();
} else {
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
}
Map* map = js_obj->map();
if (!key_is_array_index &&
@@ -5760,33 +5790,32 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) {
+RUNTIME_FUNCTION(Runtime_HasProperty) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
bool result = JSReceiver::HasProperty(receiver, key);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
- if (isolate->has_pending_exception()) return Failure::Exception();
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+ if (isolate->has_pending_exception()) return isolate->heap()->exception();
return isolate->heap()->ToBoolean(result);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) {
+RUNTIME_FUNCTION(Runtime_HasElement) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
CONVERT_SMI_ARG_CHECKED(index, 1);
bool result = JSReceiver::HasElement(receiver, index);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
- if (isolate->has_pending_exception()) return Failure::Exception();
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->ToBoolean(result);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) {
+RUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -5795,7 +5824,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) {
PropertyAttributes att = JSReceiver::GetLocalPropertyAttribute(object, key);
if (att == ABSENT || (att & DONT_ENUM) != 0) {
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->false_value();
}
ASSERT(!isolate->has_scheduled_exception());
@@ -5803,14 +5832,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) {
+RUNTIME_FUNCTION(Runtime_GetPropertyNames) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
- bool threw = false;
- Handle<JSArray> result = GetKeysFor(object, &threw);
- if (threw) return Failure::Exception();
- return *result;
+ Handle<JSArray> result;
+
+ isolate->counters()->for_in()->Increment();
+ Handle<FixedArray> elements;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, elements,
+ JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
+ return *isolate->factory()->NewJSArrayWithElements(elements);
}
@@ -5819,7 +5852,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) {
// all enumerable properties of the object and its prototypes
// have none, the map of the object. This is used to speed up
// the check for deletions during a for-in.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) {
+RUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
@@ -5829,10 +5862,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) {
HandleScope scope(isolate);
Handle<JSReceiver> object(raw_object);
- bool threw = false;
- Handle<FixedArray> content =
- GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, &threw);
- if (threw) return Failure::Exception();
+ Handle<FixedArray> content;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, content,
+ JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
// Test again, since cache may have been built by preceding call.
if (object->IsSimpleEnum()) return object->map();
@@ -5859,7 +5892,7 @@ static int LocalPrototypeChainLength(JSObject* obj) {
// Return the names of the local named properties.
// args[0]: object
// args[1]: PropertyAttributes as int
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalPropertyNames) {
+RUNTIME_FUNCTION(Runtime_GetLocalPropertyNames) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
if (!args[0]->IsJSObject()) {
@@ -5874,11 +5907,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalPropertyNames) {
if (obj->IsJSGlobalProxy()) {
// Only collect names if access is permitted.
if (obj->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(obj,
- isolate->factory()->undefined_value(),
- v8::ACCESS_KEYS)) {
- isolate->ReportFailedAccessCheckWrapper(obj, v8::ACCESS_KEYS);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ !isolate->MayNamedAccess(
+ obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
+ isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *isolate->factory()->NewJSArray(0);
}
obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
@@ -5894,11 +5926,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalPropertyNames) {
for (int i = 0; i < length; i++) {
// Only collect names if access is permitted.
if (jsproto->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(jsproto,
- isolate->factory()->undefined_value(),
- v8::ACCESS_KEYS)) {
- isolate->ReportFailedAccessCheckWrapper(jsproto, v8::ACCESS_KEYS);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ !isolate->MayNamedAccess(
+ jsproto, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
+ isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *isolate->factory()->NewJSArray(0);
}
int n;
@@ -5975,7 +6006,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalPropertyNames) {
// Return the names of the local indexed properties.
// args[0]: object
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalElementNames) {
+RUNTIME_FUNCTION(Runtime_GetLocalElementNames) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
if (!args[0]->IsJSObject()) {
@@ -5992,7 +6023,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalElementNames) {
// Return information on whether an object has a named or indexed interceptor.
// args[0]: object
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetInterceptorInfo) {
+RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
if (!args[0]->IsJSObject()) {
@@ -6010,14 +6041,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetInterceptorInfo) {
// Return property names from named interceptor.
// args[0]: object
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetNamedInterceptorPropertyNames) {
+RUNTIME_FUNCTION(Runtime_GetNamedInterceptorPropertyNames) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
if (obj->HasNamedInterceptor()) {
- v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
- if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
+ Handle<JSObject> result;
+ if (JSObject::GetKeysForNamedInterceptor(obj, obj).ToHandle(&result)) {
+ return *result;
+ }
}
return isolate->heap()->undefined_value();
}
@@ -6025,33 +6058,34 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetNamedInterceptorPropertyNames) {
// Return element names from indexed interceptor.
// args[0]: object
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetIndexedInterceptorElementNames) {
+RUNTIME_FUNCTION(Runtime_GetIndexedInterceptorElementNames) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
if (obj->HasIndexedInterceptor()) {
- v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
- if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
+ Handle<JSObject> result;
+ if (JSObject::GetKeysForIndexedInterceptor(obj, obj).ToHandle(&result)) {
+ return *result;
+ }
}
return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_LocalKeys) {
+RUNTIME_FUNCTION(Runtime_LocalKeys) {
HandleScope scope(isolate);
- ASSERT_EQ(args.length(), 1);
+ ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
Handle<JSObject> object(raw_object);
if (object->IsJSGlobalProxy()) {
// Do access checks before going to the global object.
if (object->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccessWrapper(object,
- isolate->factory()->undefined_value(),
- v8::ACCESS_KEYS)) {
- isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_KEYS);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ !isolate->MayNamedAccess(
+ object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
+ isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *isolate->factory()->NewJSArray(0);
}
@@ -6061,10 +6095,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LocalKeys) {
object = Handle<JSObject>::cast(proto);
}
- bool threw = false;
- Handle<FixedArray> contents =
- GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw);
- if (threw) return Failure::Exception();
+ Handle<FixedArray> contents;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, contents,
+ JSReceiver::GetKeys(object, JSReceiver::LOCAL_ONLY));
// Some fast paths through GetKeysInFixedArrayFor reuse a cached
// property array and since the result is mutable we have to create
@@ -6088,9 +6122,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LocalKeys) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArgumentsProperty) {
+RUNTIME_FUNCTION(Runtime_GetArgumentsProperty) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0);
// Compute the frame holding the arguments.
JavaScriptFrameIterator it(isolate);
@@ -6103,22 +6138,25 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArgumentsProperty) {
// Try to convert the key to an index. If successful and within
// index return the the argument from the frame.
uint32_t index;
- if (args[0]->ToArrayIndex(&index) && index < n) {
+ if (raw_key->ToArrayIndex(&index) && index < n) {
return frame->GetParameter(index);
}
- if (args[0]->IsSymbol()) {
+ HandleScope scope(isolate);
+ if (raw_key->IsSymbol()) {
// Lookup in the initial Object.prototype object.
- return isolate->initial_object_prototype()->GetProperty(
- Symbol::cast(args[0]));
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Object::GetProperty(isolate->initial_object_prototype(),
+ Handle<Symbol>::cast(raw_key)));
+ return *result;
}
// Convert the key to a string.
- HandleScope scope(isolate);
- bool exception = false;
- Handle<Object> converted =
- Execution::ToString(isolate, args.at<Object>(0), &exception);
- if (exception) return Failure::Exception();
+ Handle<Object> converted;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, converted, Execution::ToString(isolate, raw_key));
Handle<String> key = Handle<String>::cast(converted);
// Try to convert the string key into an array index.
@@ -6127,16 +6165,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArgumentsProperty) {
return frame->GetParameter(index);
} else {
Handle<Object> initial_prototype(isolate->initial_object_prototype());
- Handle<Object> result =
- Object::GetElement(isolate, initial_prototype, index);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Object::GetElement(isolate, initial_prototype, index));
return *result;
}
}
// Handle special arguments properties.
- if (key->Equals(isolate->heap()->length_string())) return Smi::FromInt(n);
- if (key->Equals(isolate->heap()->callee_string())) {
+ if (String::Equals(isolate->factory()->length_string(), key)) {
+ return Smi::FromInt(n);
+ }
+ if (String::Equals(isolate->factory()->callee_string(), key)) {
JSFunction* function = frame->function();
if (function->shared()->strict_mode() == STRICT) {
return isolate->Throw(*isolate->factory()->NewTypeError(
@@ -6146,11 +6187,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArgumentsProperty) {
}
// Lookup in the initial Object.prototype object.
- return isolate->initial_object_prototype()->GetProperty(*key);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Object::GetProperty(isolate->initial_object_prototype(), key));
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ToFastProperties) {
+RUNTIME_FUNCTION(Runtime_ToFastProperties) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
@@ -6161,20 +6206,21 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ToFastProperties) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ToBool) {
+RUNTIME_FUNCTION(Runtime_ToBool) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, object, 0);
- return isolate->heap()->ToBoolean(args[0]->BooleanValue());
+ return isolate->heap()->ToBoolean(object->BooleanValue());
}
// Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
// Possible optimizations: put the type string into the oddballs.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Typeof) {
+RUNTIME_FUNCTION(Runtime_Typeof) {
SealHandleScope shs(isolate);
-
- Object* obj = args[0];
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
if (obj->IsNumber()) return isolate->heap()->number_string();
HeapObject* heap_obj = HeapObject::cast(obj);
@@ -6235,18 +6281,19 @@ static int ParseDecimalInteger(const uint8_t*s, int from, int to) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_StringToNumber) {
+ HandleScope handle_scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(String, subject, 0);
- subject->TryFlatten();
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+ subject = String::Flatten(subject);
// Fast case: short integer or some sorts of junk values.
- int len = subject->length();
if (subject->IsSeqOneByteString()) {
+ int len = subject->length();
if (len == 0) return Smi::FromInt(0);
- uint8_t const* data = SeqOneByteString::cast(subject)->GetChars();
+ DisallowHeapAllocation no_gc;
+ uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
bool minus = (data[0] == '-');
int start_pos = (minus ? 1 : 0);
@@ -6254,15 +6301,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) {
return isolate->heap()->nan_value();
} else if (data[start_pos] > '9') {
// Fast check for a junk value. A valid string may start from a
- // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit or
- // the 'I' character ('Infinity'). All of that have codes not greater than
- // '9' except 'I' and &nbsp;.
+ // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
+ // or the 'I' character ('Infinity'). All of that have codes not greater
+ // than '9' except 'I' and &nbsp;.
if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
return isolate->heap()->nan_value();
}
} else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
- // The maximal/minimal smi has 10 digits. If the string has less digits we
- // know it will fit into the smi-data type.
+ // The maximal/minimal smi has 10 digits. If the string has less digits
+ // we know it will fit into the smi-data type.
int d = ParseDecimalInteger(data, start_pos, len);
if (minus) {
if (d == 0) return isolate->heap()->minus_zero_value();
@@ -6291,98 +6338,132 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToNumber) {
// Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
flags |= ALLOW_OCTAL | ALLOW_BINARY;
}
- return isolate->heap()->NumberFromDouble(
- StringToDouble(isolate->unicode_cache(), subject, flags));
+
+ return *isolate->factory()->NewNumber(StringToDouble(
+ isolate->unicode_cache(), *subject, flags));
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NewString) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NewString) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(length, 0);
CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1);
if (length == 0) return isolate->heap()->empty_string();
+ Handle<String> result;
if (is_one_byte) {
- return isolate->heap()->AllocateRawOneByteString(length);
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, isolate->factory()->NewRawOneByteString(length));
} else {
- return isolate->heap()->AllocateRawTwoByteString(length);
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, isolate->factory()->NewRawTwoByteString(length));
}
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_TruncateString) {
+RUNTIME_FUNCTION(Runtime_TruncateString) {
HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(SeqString, string, 0);
CONVERT_SMI_ARG_CHECKED(new_length, 1);
+ RUNTIME_ASSERT(new_length >= 0);
return *SeqString::Truncate(string, new_length);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_URIEscape) {
+RUNTIME_FUNCTION(Runtime_URIEscape) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
- Handle<String> string = FlattenGetString(source);
+ Handle<String> string = String::Flatten(source);
ASSERT(string->IsFlat());
- Handle<String> result = string->IsOneByteRepresentationUnderneath()
- ? URIEscape::Escape<uint8_t>(isolate, source)
- : URIEscape::Escape<uc16>(isolate, source);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<String> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ string->IsOneByteRepresentationUnderneath()
+ ? URIEscape::Escape<uint8_t>(isolate, source)
+ : URIEscape::Escape<uc16>(isolate, source));
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_URIUnescape) {
+RUNTIME_FUNCTION(Runtime_URIUnescape) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
- Handle<String> string = FlattenGetString(source);
+ Handle<String> string = String::Flatten(source);
ASSERT(string->IsFlat());
- return string->IsOneByteRepresentationUnderneath()
- ? *URIUnescape::Unescape<uint8_t>(isolate, source)
- : *URIUnescape::Unescape<uc16>(isolate, source);
+ Handle<String> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ string->IsOneByteRepresentationUnderneath()
+ ? URIUnescape::Unescape<uint8_t>(isolate, source)
+ : URIUnescape::Unescape<uc16>(isolate, source));
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONString) {
+RUNTIME_FUNCTION(Runtime_QuoteJSONString) {
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
ASSERT(args.length() == 1);
- return BasicJsonStringifier::StringifyString(isolate, string);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, BasicJsonStringifier::StringifyString(isolate, string));
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_BasicJSONStringify) {
+RUNTIME_FUNCTION(Runtime_BasicJSONStringify) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
BasicJsonStringifier stringifier(isolate);
- return stringifier.Stringify(Handle<Object>(args[0], isolate));
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, stringifier.Stringify(object));
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseInt) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_StringParseInt) {
+ HandleScope handle_scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+ CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]);
+ RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
- CONVERT_ARG_CHECKED(String, s, 0);
- CONVERT_SMI_ARG_CHECKED(radix, 1);
+ subject = String::Flatten(subject);
+ double value;
- s->TryFlatten();
+ { DisallowHeapAllocation no_gc;
+ String::FlatContent flat = subject->GetFlatContent();
- RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
- double value = StringToInt(isolate->unicode_cache(), s, radix);
- return isolate->heap()->NumberFromDouble(value);
+ // ECMA-262 section 15.1.2.3, empty string is NaN
+ if (flat.IsAscii()) {
+ value = StringToInt(
+ isolate->unicode_cache(), flat.ToOneByteVector(), radix);
+ } else {
+ value = StringToInt(
+ isolate->unicode_cache(), flat.ToUC16Vector(), radix);
+ }
+ }
+
+ return *isolate->factory()->NewNumber(value);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseFloat) {
- SealHandleScope shs(isolate);
- CONVERT_ARG_CHECKED(String, str, 0);
+RUNTIME_FUNCTION(Runtime_StringParseFloat) {
+ HandleScope shs(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
- // ECMA-262 section 15.1.2.3, empty string is NaN
- double value = StringToDouble(isolate->unicode_cache(),
- str, ALLOW_TRAILING_JUNK, OS::nan_value());
+ subject = String::Flatten(subject);
+ double value = StringToDouble(
+ isolate->unicode_cache(), *subject, ALLOW_TRAILING_JUNK, OS::nan_value());
- // Create a number object from the value.
- return isolate->heap()->NumberFromDouble(value);
+ return *isolate->factory()->NewNumber(value);
}
@@ -6396,7 +6477,7 @@ static inline bool ToUpperOverflows(uc32 character) {
template <class Converter>
-MUST_USE_RESULT static MaybeObject* ConvertCaseHelper(
+MUST_USE_RESULT static Object* ConvertCaseHelper(
Isolate* isolate,
String* string,
SeqString* result,
@@ -6619,13 +6700,11 @@ static bool FastAsciiConvert(char* dst,
template <class Converter>
-MUST_USE_RESULT static MaybeObject* ConvertCase(
- Arguments args,
+MUST_USE_RESULT static Object* ConvertCase(
+ Handle<String> s,
Isolate* isolate,
unibrow::Mapping<Converter, 128>* mapping) {
- HandleScope handle_scope(isolate);
- CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
- s = FlattenGetString(s);
+ s = String::Flatten(s);
int length = s->length();
// Assume that the string is not empty; we need this assumption later
if (length == 0) return *s;
@@ -6637,9 +6716,9 @@ MUST_USE_RESULT static MaybeObject* ConvertCase(
// might break in the future if we implement more context and locale
// dependent upper/lower conversions.
if (s->IsOneByteRepresentationUnderneath()) {
+ // Same length as input.
Handle<SeqOneByteString> result =
- isolate->factory()->NewRawOneByteString(length);
- ASSERT(!result.is_null()); // Same length as input.
+ isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
DisallowHeapAllocation no_gc;
String::FlatContent flat_content = s->GetFlatContent();
ASSERT(flat_content.IsFlat());
@@ -6650,48 +6729,52 @@ MUST_USE_RESULT static MaybeObject* ConvertCase(
length,
&has_changed_character);
// If not ASCII, we discard the result and take the 2 byte path.
- if (is_ascii) return has_changed_character ? *result : *s;
+ if (is_ascii) return has_changed_character ? *result : *s;
}
- Handle<SeqString> result;
+ Handle<SeqString> result; // Same length as input.
if (s->IsOneByteRepresentation()) {
- result = isolate->factory()->NewRawOneByteString(length);
+ result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
} else {
- result = isolate->factory()->NewRawTwoByteString(length);
+ result = isolate->factory()->NewRawTwoByteString(length).ToHandleChecked();
}
- ASSERT(!result.is_null()); // Same length as input.
- MaybeObject* maybe = ConvertCaseHelper(isolate, *s, *result, length, mapping);
- Object* answer;
- if (!maybe->ToObject(&answer)) return maybe;
- if (answer->IsString()) return answer;
+ Object* answer = ConvertCaseHelper(isolate, *s, *result, length, mapping);
+ if (answer->IsException() || answer->IsString()) return answer;
ASSERT(answer->IsSmi());
length = Smi::cast(answer)->value();
if (s->IsOneByteRepresentation() && length > 0) {
- result = isolate->factory()->NewRawOneByteString(length);
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, isolate->factory()->NewRawOneByteString(length));
} else {
if (length < 0) length = -length;
- result = isolate->factory()->NewRawTwoByteString(length);
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, isolate->factory()->NewRawTwoByteString(length));
}
- RETURN_IF_EMPTY_HANDLE(isolate, result);
return ConvertCaseHelper(isolate, *s, *result, length, mapping);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) {
+RUNTIME_FUNCTION(Runtime_StringToLowerCase) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
return ConvertCase(
- args, isolate, isolate->runtime_state()->to_lower_mapping());
+ s, isolate, isolate->runtime_state()->to_lower_mapping());
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToUpperCase) {
+RUNTIME_FUNCTION(Runtime_StringToUpperCase) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
return ConvertCase(
- args, isolate, isolate->runtime_state()->to_upper_mapping());
+ s, isolate, isolate->runtime_state()->to_upper_mapping());
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) {
+RUNTIME_FUNCTION(Runtime_StringTrim) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
@@ -6699,7 +6782,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) {
CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2);
- string = FlattenGetString(string);
+ string = String::Flatten(string);
int length = string->length();
int left = 0;
@@ -6724,12 +6807,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
+RUNTIME_FUNCTION(Runtime_StringSplit) {
HandleScope handle_scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
+ RUNTIME_ASSERT(limit > 0);
int subject_length = subject->length();
int pattern_length = pattern->length();
@@ -6755,7 +6839,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
// isn't empty, we can never create more parts than ~half the length
// of the subject.
- if (!subject->IsFlat()) FlattenString(subject);
+ subject = String::Flatten(subject);
+ pattern = String::Flatten(pattern);
static const int kMaxInitialListCapacity = 16;
@@ -6764,7 +6849,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
// Find (up to limit) indices of separator and end-of-string in subject
int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
ZoneList<int> indices(initial_capacity, zone_scope.zone());
- if (!pattern->IsFlat()) FlattenString(pattern);
FindStringIndicesDispatch(isolate, *subject, *pattern,
&indices, limit, zone_scope.zone());
@@ -6802,10 +6886,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
if (limit == 0xffffffffu) {
if (result->HasFastObjectElements()) {
- RegExpResultsCache::Enter(isolate->heap(),
- *subject,
- *pattern,
- *elements,
+ RegExpResultsCache::Enter(isolate,
+ subject,
+ pattern,
+ elements,
RegExpResultsCache::STRING_SPLIT_SUBSTRINGS);
}
}
@@ -6849,25 +6933,21 @@ static int CopyCachedAsciiCharsToArray(Heap* heap,
// Converts a String to JSArray.
// For example, "foo" => ["f", "o", "o"].
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) {
+RUNTIME_FUNCTION(Runtime_StringToArray) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
- s = FlattenGetString(s);
+ s = String::Flatten(s);
const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
Handle<FixedArray> elements;
int position = 0;
if (s->IsFlat() && s->IsOneByteRepresentation()) {
// Try using cached chars where possible.
- Object* obj;
- { MaybeObject* maybe_obj =
- isolate->heap()->AllocateUninitializedFixedArray(length);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- elements = Handle<FixedArray>(FixedArray::cast(obj), isolate);
+ elements = isolate->factory()->NewUninitializedFixedArray(length);
+
DisallowHeapAllocation no_gc;
String::FlatContent content = s->GetFlatContent();
if (content.IsAscii()) {
@@ -6888,7 +6968,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) {
}
for (int i = position; i < length; ++i) {
Handle<Object> str =
- LookupSingleCharacterStringFromCode(isolate, s->Get(i));
+ isolate->factory()->LookupSingleCharacterStringFromCode(s->Get(i));
elements->set(i, *str);
}
@@ -6902,11 +6982,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStringWrapper) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NewStringWrapper) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(String, value, 0);
- return value->ToObject(isolate);
+ CONVERT_ARG_HANDLE_CHECKED(String, value, 0);
+ return *Object::ToObject(isolate, value).ToHandleChecked();
}
@@ -6917,91 +6997,70 @@ bool Runtime::IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NumberToString) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(RuntimeHidden_NumberToString) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
- Object* number = args[0];
- RUNTIME_ASSERT(number->IsNumber());
-
- return isolate->heap()->NumberToString(number);
+ return *isolate->factory()->NumberToString(number);
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NumberToStringSkipCache) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(RuntimeHidden_NumberToStringSkipCache) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
- Object* number = args[0];
- RUNTIME_ASSERT(number->IsNumber());
-
- return isolate->heap()->NumberToString(number, false);
+ return *isolate->factory()->NumberToString(number, false);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToInteger) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberToInteger) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(number, 0);
-
- // We do not include 0 so that we don't have to treat +0 / -0 cases.
- if (number > 0 && number <= Smi::kMaxValue) {
- return Smi::FromInt(static_cast<int>(number));
- }
- return isolate->heap()->NumberFromDouble(DoubleToInteger(number));
+ return *isolate->factory()->NewNumber(DoubleToInteger(number));
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToIntegerMapMinusZero) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(number, 0);
-
- // We do not include 0 so that we don't have to treat +0 / -0 cases.
- if (number > 0 && number <= Smi::kMaxValue) {
- return Smi::FromInt(static_cast<int>(number));
- }
-
double double_value = DoubleToInteger(number);
// Map both -0 and +0 to +0.
if (double_value == 0) double_value = 0;
- return isolate->heap()->NumberFromDouble(double_value);
+ return *isolate->factory()->NewNumber(double_value);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSUint32) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberToJSUint32) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
- return isolate->heap()->NumberFromUint32(number);
+ return *isolate->factory()->NewNumberFromUint(number);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSInt32) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberToJSInt32) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(number, 0);
-
- // We do not include 0 so that we don't have to treat +0 / -0 cases.
- if (number > 0 && number <= Smi::kMaxValue) {
- return Smi::FromInt(static_cast<int>(number));
- }
- return isolate->heap()->NumberFromInt32(DoubleToInt32(number));
+ return *isolate->factory()->NewNumberFromInt(DoubleToInt32(number));
}
// Converts a Number to a Smi, if possible. Returns NaN if the number is not
// a small integer.
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NumberToSmi) {
+RUNTIME_FUNCTION(RuntimeHidden_NumberToSmi) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
-
- Object* obj = args[0];
+ CONVERT_ARG_CHECKED(Object, obj, 0);
if (obj->IsSmi()) {
return obj;
}
@@ -7016,101 +7075,91 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NumberToSmi) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_AllocateHeapNumber) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(RuntimeHidden_AllocateHeapNumber) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 0);
- return isolate->heap()->AllocateHeapNumber(0);
+ return *isolate->factory()->NewHeapNumber(0);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAdd) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberAdd) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
CONVERT_DOUBLE_ARG_CHECKED(y, 1);
- return isolate->heap()->NumberFromDouble(x + y);
+ return *isolate->factory()->NewNumber(x + y);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberSub) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberSub) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
CONVERT_DOUBLE_ARG_CHECKED(y, 1);
- return isolate->heap()->NumberFromDouble(x - y);
+ return *isolate->factory()->NewNumber(x - y);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMul) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberMul) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
CONVERT_DOUBLE_ARG_CHECKED(y, 1);
- return isolate->heap()->NumberFromDouble(x * y);
+ return *isolate->factory()->NewNumber(x * y);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberUnaryMinus) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberUnaryMinus) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- return isolate->heap()->NumberFromDouble(-x);
+ return *isolate->factory()->NewNumber(-x);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAlloc) {
- SealHandleScope shs(isolate);
- ASSERT(args.length() == 0);
-
- return isolate->heap()->NumberFromDouble(9876543210.0);
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberDiv) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberDiv) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
CONVERT_DOUBLE_ARG_CHECKED(y, 1);
- return isolate->heap()->NumberFromDouble(x / y);
+ return *isolate->factory()->NewNumber(x / y);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMod) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberMod) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-
- x = modulo(x, y);
- // NumberFromDouble may return a Smi instead of a Number object
- return isolate->heap()->NumberFromDouble(x);
+ return *isolate->factory()->NewNumber(modulo(x, y));
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberImul) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberImul) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
- return isolate->heap()->NumberFromInt32(x * y);
+ return *isolate->factory()->NewNumberFromInt(x * y);
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_StringAdd) {
+RUNTIME_FUNCTION(RuntimeHidden_StringAdd) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
isolate->counters()->string_add_runtime()->Increment();
- Handle<String> result = isolate->factory()->NewConsString(str1, str2);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<String> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, isolate->factory()->NewConsString(str1, str2));
return *result;
}
@@ -7120,6 +7169,7 @@ static inline void StringBuilderConcatHelper(String* special,
sinkchar* sink,
FixedArray* fixed_array,
int array_length) {
+ DisallowHeapAllocation no_gc;
int position = 0;
for (int i = 0; i < array_length; i++) {
Object* element = fixed_array->get(i);
@@ -7154,36 +7204,13 @@ static inline void StringBuilderConcatHelper(String* special,
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
- HandleScope scope(isolate);
- ASSERT(args.length() == 3);
- CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
- if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
- int array_length = args.smi_at(1);
- CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
-
- // This assumption is used by the slice encoding in one or two smis.
- ASSERT(Smi::kMaxValue >= String::kMaxLength);
-
- JSObject::EnsureCanContainHeapObjectElements(array);
-
- int special_length = special->length();
- if (!array->HasFastObjectElements()) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
- }
- FixedArray* fixed_array = FixedArray::cast(array->elements());
- if (fixed_array->length() < array_length) {
- array_length = fixed_array->length();
- }
-
- if (array_length == 0) {
- return isolate->heap()->empty_string();
- } else if (array_length == 1) {
- Object* first = fixed_array->get(0);
- if (first->IsString()) return first;
- }
-
- bool one_byte = special->HasOnlyOneByteChars();
+// Returns the result length of the concatenation.
+// On illegal argument, -1 is returned.
+static inline int StringBuilderConcatLength(int special_length,
+ FixedArray* fixed_array,
+ int array_length,
+ bool* one_byte) {
+ DisallowHeapAllocation no_gc;
int position = 0;
for (int i = 0; i < array_length; i++) {
int increment = 0;
@@ -7202,76 +7229,113 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
len = -smi_value;
// Get the position and check that it is a positive smi.
i++;
- if (i >= array_length) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
- }
+ if (i >= array_length) return -1;
Object* next_smi = fixed_array->get(i);
- if (!next_smi->IsSmi()) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
- }
+ if (!next_smi->IsSmi()) return -1;
pos = Smi::cast(next_smi)->value();
- if (pos < 0) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
- }
+ if (pos < 0) return -1;
}
ASSERT(pos >= 0);
ASSERT(len >= 0);
- if (pos > special_length || len > special_length - pos) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
- }
+ if (pos > special_length || len > special_length - pos) return -1;
increment = len;
} else if (elt->IsString()) {
String* element = String::cast(elt);
int element_length = element->length();
increment = element_length;
- if (one_byte && !element->HasOnlyOneByteChars()) {
- one_byte = false;
+ if (*one_byte && !element->HasOnlyOneByteChars()) {
+ *one_byte = false;
}
} else {
- ASSERT(!elt->IsTheHole());
- return isolate->Throw(isolate->heap()->illegal_argument_string());
+ return -1;
}
if (increment > String::kMaxLength - position) {
- return isolate->ThrowInvalidStringLength();
+ return kMaxInt; // Provoke throw on allocation.
}
position += increment;
}
+ return position;
+}
- int length = position;
- Object* object;
- if (one_byte) {
- { MaybeObject* maybe_object =
- isolate->heap()->AllocateRawOneByteString(length);
- if (!maybe_object->ToObject(&object)) return maybe_object;
+RUNTIME_FUNCTION(Runtime_StringBuilderConcat) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
+ if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
+ CONVERT_SMI_ARG_CHECKED(array_length, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
+
+ size_t actual_array_length = 0;
+ RUNTIME_ASSERT(
+ TryNumberToSize(isolate, array->length(), &actual_array_length));
+ RUNTIME_ASSERT(array_length >= 0);
+ RUNTIME_ASSERT(static_cast<size_t>(array_length) <= actual_array_length);
+
+ // This assumption is used by the slice encoding in one or two smis.
+ ASSERT(Smi::kMaxValue >= String::kMaxLength);
+
+ RUNTIME_ASSERT(array->HasFastElements());
+ JSObject::EnsureCanContainHeapObjectElements(array);
+
+ int special_length = special->length();
+ if (!array->HasFastObjectElements()) {
+ return isolate->Throw(isolate->heap()->illegal_argument_string());
+ }
+
+ int length;
+ bool one_byte = special->HasOnlyOneByteChars();
+
+ { DisallowHeapAllocation no_gc;
+ FixedArray* fixed_array = FixedArray::cast(array->elements());
+ if (fixed_array->length() < array_length) {
+ array_length = fixed_array->length();
+ }
+
+ if (array_length == 0) {
+ return isolate->heap()->empty_string();
+ } else if (array_length == 1) {
+ Object* first = fixed_array->get(0);
+ if (first->IsString()) return first;
}
- SeqOneByteString* answer = SeqOneByteString::cast(object);
+ length = StringBuilderConcatLength(
+ special_length, fixed_array, array_length, &one_byte);
+ }
+
+ if (length == -1) {
+ return isolate->Throw(isolate->heap()->illegal_argument_string());
+ }
+
+ if (one_byte) {
+ Handle<SeqOneByteString> answer;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, answer,
+ isolate->factory()->NewRawOneByteString(length));
StringBuilderConcatHelper(*special,
answer->GetChars(),
- fixed_array,
+ FixedArray::cast(array->elements()),
array_length);
- return answer;
+ return *answer;
} else {
- { MaybeObject* maybe_object =
- isolate->heap()->AllocateRawTwoByteString(length);
- if (!maybe_object->ToObject(&object)) return maybe_object;
- }
- SeqTwoByteString* answer = SeqTwoByteString::cast(object);
+ Handle<SeqTwoByteString> answer;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, answer,
+ isolate->factory()->NewRawTwoByteString(length));
StringBuilderConcatHelper(*special,
answer->GetChars(),
- fixed_array,
+ FixedArray::cast(array->elements()),
array_length);
- return answer;
+ return *answer;
}
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
+RUNTIME_FUNCTION(Runtime_StringBuilderJoin) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
- int array_length = args.smi_at(1);
+ CONVERT_SMI_ARG_CHECKED(array_length, 1);
CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
RUNTIME_ASSERT(array->HasFastObjectElements());
@@ -7289,6 +7353,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
}
int separator_length = separator->length();
+ RUNTIME_ASSERT(separator_length > 0);
int max_nof_separators =
(String::kMaxLength + separator_length - 1) / separator_length;
if (max_nof_separators < (array_length - 1)) {
@@ -7308,9 +7373,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
length += increment;
}
- Handle<SeqTwoByteString> answer =
- isolate->factory()->NewRawTwoByteString(length);
- RETURN_IF_EMPTY_HANDLE(isolate, answer);
+ Handle<SeqTwoByteString> answer;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, answer,
+ isolate->factory()->NewRawTwoByteString(length));
DisallowHeapAllocation no_gc;
@@ -7349,6 +7415,7 @@ static void JoinSparseArrayWithSeparator(FixedArray* elements,
uint32_t array_length,
String* separator,
Vector<Char> buffer) {
+ DisallowHeapAllocation no_gc;
int previous_separator_position = 0;
int separator_length = separator->length();
int cursor = 0;
@@ -7384,41 +7451,48 @@ static void JoinSparseArrayWithSeparator(FixedArray* elements,
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
+RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- CONVERT_ARG_CHECKED(JSArray, elements_array, 0);
- RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0);
CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
- CONVERT_ARG_CHECKED(String, separator, 2);
+ CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
// elements_array is fast-mode JSarray of alternating positions
// (increasing order) and strings.
+ RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
// array_length is length of original array (used to add separators);
// separator is string to put between elements. Assumed to be non-empty.
+ RUNTIME_ASSERT(array_length > 0);
// Find total length of join result.
int string_length = 0;
bool is_ascii = separator->IsOneByteRepresentation();
bool overflow = false;
- CONVERT_NUMBER_CHECKED(int, elements_length,
- Int32, elements_array->length());
+ CONVERT_NUMBER_CHECKED(int, elements_length, Int32, elements_array->length());
+ RUNTIME_ASSERT(elements_length <= elements_array->elements()->length());
RUNTIME_ASSERT((elements_length & 1) == 0); // Even length.
FixedArray* elements = FixedArray::cast(elements_array->elements());
for (int i = 0; i < elements_length; i += 2) {
RUNTIME_ASSERT(elements->get(i)->IsNumber());
RUNTIME_ASSERT(elements->get(i + 1)->IsString());
- String* string = String::cast(elements->get(i + 1));
- int length = string->length();
- if (is_ascii && !string->IsOneByteRepresentation()) {
- is_ascii = false;
- }
- if (length > String::kMaxLength ||
- String::kMaxLength - length < string_length) {
- overflow = true;
- break;
+ }
+
+ { DisallowHeapAllocation no_gc;
+ for (int i = 0; i < elements_length; i += 2) {
+ String* string = String::cast(elements->get(i + 1));
+ int length = string->length();
+ if (is_ascii && !string->IsOneByteRepresentation()) {
+ is_ascii = false;
+ }
+ if (length > String::kMaxLength ||
+ String::kMaxLength - length < string_length) {
+ overflow = true;
+ break;
+ }
+ string_length += length;
}
- string_length += length;
}
+
int separator_length = separator->length();
if (!overflow && separator_length > 0) {
if (array_length <= 0x7fffffffu) {
@@ -7445,97 +7519,91 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
}
if (is_ascii) {
- MaybeObject* result_allocation =
- isolate->heap()->AllocateRawOneByteString(string_length);
- if (result_allocation->IsFailure()) return result_allocation;
- SeqOneByteString* result_string =
- SeqOneByteString::cast(result_allocation->ToObjectUnchecked());
- JoinSparseArrayWithSeparator<uint8_t>(elements,
- elements_length,
- array_length,
- separator,
- Vector<uint8_t>(
- result_string->GetChars(),
- string_length));
- return result_string;
+ Handle<SeqOneByteString> result = isolate->factory()->NewRawOneByteString(
+ string_length).ToHandleChecked();
+ JoinSparseArrayWithSeparator<uint8_t>(
+ FixedArray::cast(elements_array->elements()),
+ elements_length,
+ array_length,
+ *separator,
+ Vector<uint8_t>(result->GetChars(), string_length));
+ return *result;
} else {
- MaybeObject* result_allocation =
- isolate->heap()->AllocateRawTwoByteString(string_length);
- if (result_allocation->IsFailure()) return result_allocation;
- SeqTwoByteString* result_string =
- SeqTwoByteString::cast(result_allocation->ToObjectUnchecked());
- JoinSparseArrayWithSeparator<uc16>(elements,
- elements_length,
- array_length,
- separator,
- Vector<uc16>(result_string->GetChars(),
- string_length));
- return result_string;
+ Handle<SeqTwoByteString> result = isolate->factory()->NewRawTwoByteString(
+ string_length).ToHandleChecked();
+ JoinSparseArrayWithSeparator<uc16>(
+ FixedArray::cast(elements_array->elements()),
+ elements_length,
+ array_length,
+ *separator,
+ Vector<uc16>(result->GetChars(), string_length));
+ return *result;
}
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberOr) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberOr) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
- return isolate->heap()->NumberFromInt32(x | y);
+ return *isolate->factory()->NewNumberFromInt(x | y);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAnd) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberAnd) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
- return isolate->heap()->NumberFromInt32(x & y);
+ return *isolate->factory()->NewNumberFromInt(x & y);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberXor) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberXor) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
- return isolate->heap()->NumberFromInt32(x ^ y);
+ return *isolate->factory()->NewNumberFromInt(x ^ y);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberShl) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberShl) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
- return isolate->heap()->NumberFromInt32(x << (y & 0x1f));
+ return *isolate->factory()->NewNumberFromInt(x << (y & 0x1f));
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberShr) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberShr) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
- return isolate->heap()->NumberFromUint32(x >> (y & 0x1f));
+ return *isolate->factory()->NewNumberFromUint(x >> (y & 0x1f));
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberSar) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_NumberSar) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
- return isolate->heap()->NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f));
+ return *isolate->factory()->NewNumberFromInt(
+ ArithmeticShiftRight(x, y & 0x1f));
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberEquals) {
+RUNTIME_FUNCTION(Runtime_NumberEquals) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
@@ -7554,14 +7622,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberEquals) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_StringEquals) {
+ HandleScope handle_scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(String, x, 0);
- CONVERT_ARG_CHECKED(String, y, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
- bool not_equal = !x->Equals(y);
+ bool not_equal = !String::Equals(x, y);
// This is slightly convoluted because the value that signifies
// equality is 0 and inequality is 1 so we have to negate the result
// from String::Equals.
@@ -7572,13 +7640,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberCompare) {
+RUNTIME_FUNCTION(Runtime_NumberCompare) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 3);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
CONVERT_DOUBLE_ARG_CHECKED(y, 1);
- if (std::isnan(x) || std::isnan(y)) return args[2];
+ CONVERT_ARG_HANDLE_CHECKED(Object, uncomparable_result, 2)
+ if (std::isnan(x) || std::isnan(y)) return *uncomparable_result;
if (x == y) return Smi::FromInt(EQUAL);
if (isless(x, y)) return Smi::FromInt(LESS);
return Smi::FromInt(GREATER);
@@ -7587,7 +7656,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberCompare) {
// Compare two Smis as if they were converted to strings and then
// compared lexicographically.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SmiLexicographicCompare) {
+RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(x_value, 0);
@@ -7662,27 +7731,33 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SmiLexicographicCompare) {
}
-static Object* StringCharacterStreamCompare(RuntimeState* state,
- String* x,
- String* y) {
- StringCharacterStream stream_x(x, state->string_iterator_compare_x());
- StringCharacterStream stream_y(y, state->string_iterator_compare_y());
- while (stream_x.HasMore() && stream_y.HasMore()) {
- int d = stream_x.GetNext() - stream_y.GetNext();
- if (d < 0) return Smi::FromInt(LESS);
- else if (d > 0) return Smi::FromInt(GREATER);
+RUNTIME_FUNCTION(RuntimeHidden_StringCompare) {
+ HandleScope handle_scope(isolate);
+ ASSERT(args.length() == 2);
+
+ CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
+
+ isolate->counters()->string_compare_runtime()->Increment();
+
+ // A few fast case tests before we flatten.
+ if (x.is_identical_to(y)) return Smi::FromInt(EQUAL);
+ if (y->length() == 0) {
+ if (x->length() == 0) return Smi::FromInt(EQUAL);
+ return Smi::FromInt(GREATER);
+ } else if (x->length() == 0) {
+ return Smi::FromInt(LESS);
}
- // x is (non-trivial) prefix of y:
- if (stream_y.HasMore()) return Smi::FromInt(LESS);
- // y is prefix of x:
- return Smi::FromInt(stream_x.HasMore() ? GREATER : EQUAL);
-}
+ int d = x->Get(0) - y->Get(0);
+ if (d < 0) return Smi::FromInt(LESS);
+ else if (d > 0) return Smi::FromInt(GREATER);
+ // Slow case.
+ x = String::Flatten(x);
+ y = String::Flatten(y);
-static Object* FlatStringCompare(String* x, String* y) {
- ASSERT(x->IsFlat());
- ASSERT(y->IsFlat());
+ DisallowHeapAllocation no_gc;
Object* equal_prefix_result = Smi::FromInt(EQUAL);
int prefix_length = x->length();
if (y->length() < prefix_length) {
@@ -7692,7 +7767,6 @@ static Object* FlatStringCompare(String* x, String* y) {
equal_prefix_result = Smi::FromInt(LESS);
}
int r;
- DisallowHeapAllocation no_gc;
String::FlatContent x_content = x->GetFlatContent();
String::FlatContent y_content = y->GetFlatContent();
if (x_content.IsAscii()) {
@@ -7720,97 +7794,60 @@ static Object* FlatStringCompare(String* x, String* y) {
} else {
result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
}
- ASSERT(result ==
- StringCharacterStreamCompare(x->GetIsolate()->runtime_state(), x, y));
return result;
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_StringCompare) {
- SealHandleScope shs(isolate);
- ASSERT(args.length() == 2);
-
- CONVERT_ARG_CHECKED(String, x, 0);
- CONVERT_ARG_CHECKED(String, y, 1);
-
- isolate->counters()->string_compare_runtime()->Increment();
-
- // A few fast case tests before we flatten.
- if (x == y) return Smi::FromInt(EQUAL);
- if (y->length() == 0) {
- if (x->length() == 0) return Smi::FromInt(EQUAL);
- return Smi::FromInt(GREATER);
- } else if (x->length() == 0) {
- return Smi::FromInt(LESS);
- }
-
- int d = x->Get(0) - y->Get(0);
- if (d < 0) return Smi::FromInt(LESS);
- else if (d > 0) return Smi::FromInt(GREATER);
-
- Object* obj;
- { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(x);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(y);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
-
- return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y)
- : StringCharacterStreamCompare(isolate->runtime_state(), x, y);
-}
-
-
-#define RUNTIME_UNARY_MATH(NAME) \
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_##NAME) { \
- SealHandleScope shs(isolate); \
+#define RUNTIME_UNARY_MATH(Name, name) \
+RUNTIME_FUNCTION(Runtime_Math##Name) { \
+ HandleScope scope(isolate); \
ASSERT(args.length() == 1); \
- isolate->counters()->math_##NAME()->Increment(); \
+ isolate->counters()->math_##name()->Increment(); \
CONVERT_DOUBLE_ARG_CHECKED(x, 0); \
- return isolate->heap()->AllocateHeapNumber(std::NAME(x)); \
+ return *isolate->factory()->NewHeapNumber(std::name(x)); \
}
-RUNTIME_UNARY_MATH(acos)
-RUNTIME_UNARY_MATH(asin)
-RUNTIME_UNARY_MATH(atan)
-RUNTIME_UNARY_MATH(log)
+RUNTIME_UNARY_MATH(Acos, acos)
+RUNTIME_UNARY_MATH(Asin, asin)
+RUNTIME_UNARY_MATH(Atan, atan)
+RUNTIME_UNARY_MATH(Log, log)
#undef RUNTIME_UNARY_MATH
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DoubleHi) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_DoubleHi) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
uint64_t integer = double_to_uint64(x);
integer = (integer >> 32) & 0xFFFFFFFFu;
- return isolate->heap()->NumberFromDouble(static_cast<int32_t>(integer));
+ return *isolate->factory()->NewNumber(static_cast<int32_t>(integer));
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DoubleLo) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_DoubleLo) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- return isolate->heap()->NumberFromDouble(
+ return *isolate->factory()->NewNumber(
static_cast<int32_t>(double_to_uint64(x) & 0xFFFFFFFFu));
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ConstructDouble) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_ConstructDouble) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
- return isolate->heap()->AllocateHeapNumber(uint64_to_double(result));
+ return *isolate->factory()->NewNumber(uint64_to_double(result));
}
static const double kPiDividedBy4 = 0.78539816339744830962;
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan2) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_MathAtan2) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
isolate->counters()->math_atan2()->Increment();
@@ -7828,35 +7865,35 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan2) {
} else {
result = std::atan2(x, y);
}
- return isolate->heap()->AllocateHeapNumber(result);
+ return *isolate->factory()->NewNumber(result);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_exp) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_MathExp) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
isolate->counters()->math_exp()->Increment();
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
lazily_initialize_fast_exp();
- return isolate->heap()->NumberFromDouble(fast_exp(x));
+ return *isolate->factory()->NewNumber(fast_exp(x));
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_floor) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_MathFloor) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
isolate->counters()->math_floor()->Increment();
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- return isolate->heap()->NumberFromDouble(std::floor(x));
+ return *isolate->factory()->NewNumber(std::floor(x));
}
// Slow version of Math.pow. We check for fast paths for special cases.
// Used if SSE2/VFP3 is not available.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(RuntimeHidden_MathPowSlow) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
isolate->counters()->math_pow()->Increment();
@@ -7866,20 +7903,20 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow) {
// custom powi() function than the generic pow().
if (args[1]->IsSmi()) {
int y = args.smi_at(1);
- return isolate->heap()->NumberFromDouble(power_double_int(x, y));
+ return *isolate->factory()->NewNumber(power_double_int(x, y));
}
CONVERT_DOUBLE_ARG_CHECKED(y, 1);
double result = power_helper(x, y);
if (std::isnan(result)) return isolate->heap()->nan_value();
- return isolate->heap()->AllocateHeapNumber(result);
+ return *isolate->factory()->NewNumber(result);
}
// Fast version of Math.pow if we know that y is not an integer and y is not
// -0.5 or 0.5. Used as slow case from full codegen.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow_cfunction) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(RuntimeHidden_MathPow) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
isolate->counters()->math_pow()->Increment();
@@ -7890,23 +7927,23 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow_cfunction) {
} else {
double result = power_double_double(x, y);
if (std::isnan(result)) return isolate->heap()->nan_value();
- return isolate->heap()->AllocateHeapNumber(result);
+ return *isolate->factory()->NewNumber(result);
}
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_RoundNumber) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_RoundNumber) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
isolate->counters()->math_round()->Increment();
- if (!args[0]->IsHeapNumber()) {
- // Must be smi. Return the argument unchanged for all the other types
- // to make fuzz-natives test happy.
- return args[0];
+ if (!input->IsHeapNumber()) {
+ ASSERT(input->IsSmi());
+ return *input;
}
- HeapNumber* number = reinterpret_cast<HeapNumber*>(args[0]);
+ Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
double value = number->value();
int exponent = number->get_exponent();
@@ -7928,48 +7965,50 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RoundNumber) {
// If the magnitude is big enough, there's no place for fraction part. If we
// try to add 0.5 to this number, 1.0 will be added instead.
if (exponent >= 52) {
- return number;
+ return *number;
}
if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
// Do not call NumberFromDouble() to avoid extra checks.
- return isolate->heap()->AllocateHeapNumber(std::floor(value + 0.5));
+ return *isolate->factory()->NewNumber(std::floor(value + 0.5));
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sqrt) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_MathSqrt) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
isolate->counters()->math_sqrt()->Increment();
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- return isolate->heap()->AllocateHeapNumber(fast_sqrt(x));
+ return *isolate->factory()->NewNumber(fast_sqrt(x));
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_fround) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_MathFround) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
float xf = static_cast<float>(x);
- return isolate->heap()->AllocateHeapNumber(xf);
+ return *isolate->factory()->NewNumber(xf);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) {
+RUNTIME_FUNCTION(Runtime_DateMakeDay) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(year, 0);
CONVERT_SMI_ARG_CHECKED(month, 1);
- return Smi::FromInt(isolate->date_cache()->DaysFromYearMonth(year, month));
+ int days = isolate->date_cache()->DaysFromYearMonth(year, month);
+ RUNTIME_ASSERT(Smi::IsValid(days));
+ return Smi::FromInt(days);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DateSetValue) {
+RUNTIME_FUNCTION(Runtime_DateSetValue) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
@@ -7979,40 +8018,38 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateSetValue) {
DateCache* date_cache = isolate->date_cache();
- Object* value = NULL;
+ Handle<Object> value;;
bool is_value_nan = false;
if (std::isnan(time)) {
- value = isolate->heap()->nan_value();
+ value = isolate->factory()->nan_value();
is_value_nan = true;
} else if (!is_utc &&
(time < -DateCache::kMaxTimeBeforeUTCInMs ||
time > DateCache::kMaxTimeBeforeUTCInMs)) {
- value = isolate->heap()->nan_value();
+ value = isolate->factory()->nan_value();
is_value_nan = true;
} else {
time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
if (time < -DateCache::kMaxTimeInMs ||
time > DateCache::kMaxTimeInMs) {
- value = isolate->heap()->nan_value();
+ value = isolate->factory()->nan_value();
is_value_nan = true;
} else {
- MaybeObject* maybe_result =
- isolate->heap()->AllocateHeapNumber(DoubleToInteger(time));
- if (!maybe_result->ToObject(&value)) return maybe_result;
+ value = isolate->factory()->NewNumber(DoubleToInteger(time));
}
}
- date->SetValue(value, is_value_nan);
- return value;
+ date->SetValue(*value, is_value_nan);
+ return *value;
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NewArgumentsFast) {
+RUNTIME_FUNCTION(RuntimeHidden_NewArgumentsFast) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- Handle<JSFunction> callee = args.at<JSFunction>(0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
Object** parameters = reinterpret_cast<Object**>(args[1]);
- const int argument_count = Smi::cast(args[2])->value();
+ CONVERT_SMI_ARG_CHECKED(argument_count, 2);
Handle<JSObject> result =
isolate->factory()->NewArgumentsObject(callee, argument_count);
@@ -8026,11 +8063,10 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NewArgumentsFast) {
parameter_map->set_map(
isolate->heap()->sloppy_arguments_elements_map());
- Handle<Map> old_map(result->map());
- Handle<Map> new_map = isolate->factory()->CopyMap(old_map);
- new_map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
+ Handle<Map> map = Map::Copy(handle(result->map()));
+ map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
- result->set_map(*new_map);
+ result->set_map(*map);
result->set_elements(*parameter_map);
// Store the context and the arguments array at the beginning of the
@@ -8101,54 +8137,42 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NewArgumentsFast) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NewStrictArgumentsFast) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(RuntimeHidden_NewStrictArgumentsFast) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 3);
-
- JSFunction* callee = JSFunction::cast(args[0]);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
Object** parameters = reinterpret_cast<Object**>(args[1]);
- const int length = args.smi_at(2);
+ CONVERT_SMI_ARG_CHECKED(length, 2);
- Object* result;
- { MaybeObject* maybe_result =
- isolate->heap()->AllocateArgumentsObject(callee, length);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- // Allocate the elements if needed.
- if (length > 0) {
- // Allocate the fixed array.
- FixedArray* array;
- { MaybeObject* maybe_obj =
- isolate->heap()->AllocateUninitializedFixedArray(length);
- if (!maybe_obj->To(&array)) return maybe_obj;
- }
+ Handle<JSObject> result =
+ isolate->factory()->NewArgumentsObject(callee, length);
+ if (length > 0) {
+ Handle<FixedArray> array =
+ isolate->factory()->NewUninitializedFixedArray(length);
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
for (int i = 0; i < length; i++) {
array->set(i, *--parameters, mode);
}
- JSObject::cast(result)->set_elements(array);
+ result->set_elements(*array);
}
- return result;
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NewClosureFromStubFailure) {
+RUNTIME_FUNCTION(RuntimeHidden_NewClosureFromStubFailure) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
Handle<Context> context(isolate->context());
PretenureFlag pretenure_flag = NOT_TENURED;
- Handle<JSFunction> result =
- isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
- context,
- pretenure_flag);
- return *result;
+ return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
+ shared, context, pretenure_flag);
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NewClosure) {
+RUNTIME_FUNCTION(RuntimeHidden_NewClosure) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
@@ -8158,11 +8182,8 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NewClosure) {
// The caller ensures that we pretenure closures that are assigned
// directly to properties.
PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
- Handle<JSFunction> result =
- isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
- context,
- pretenure_flag);
- return *result;
+ return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
+ shared, context, pretenure_flag);
}
@@ -8216,7 +8237,7 @@ static SmartArrayPointer<Handle<Object> > GetCallerArguments(
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionBindArguments) {
+RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
@@ -8231,10 +8252,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionBindArguments) {
GetCallerArguments(isolate, 0, &argc);
// Don't count the this-arg.
if (argc > 0) {
- ASSERT(*arguments[0] == args[2]);
+ RUNTIME_ASSERT(*arguments[0] == args[2]);
argc--;
} else {
- ASSERT(args[2]->IsUndefined());
+ RUNTIME_ASSERT(args[2]->IsUndefined());
}
// Initialize array of bindings (function, this, and any existing arguments
// if the function was already bound).
@@ -8243,6 +8264,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionBindArguments) {
if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
Handle<FixedArray> old_bindings(
JSFunction::cast(*bindee)->function_bindings());
+ RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex);
new_bindings =
isolate->factory()->NewFixedArray(old_bindings->length() + argc);
bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex),
@@ -8271,12 +8293,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionBindArguments) {
Handle<Object> new_length(args.at<Object>(3));
PropertyAttributes attr =
static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
- ForceSetProperty(bound_function, length_string, new_length, attr);
+ Runtime::ForceSetObjectProperty(
+ bound_function, length_string, new_length, attr).Assert();
return *bound_function;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_BoundFunctionGetBindings) {
+RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) {
HandleScope handles(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
@@ -8284,7 +8307,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_BoundFunctionGetBindings) {
Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
if (function->shared()->bound()) {
Handle<FixedArray> bindings(function->function_bindings());
- ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map());
+ RUNTIME_ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map());
return *isolate->factory()->NewJSArrayWithElements(bindings);
}
}
@@ -8292,7 +8315,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_BoundFunctionGetBindings) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObjectFromBound) {
+RUNTIME_FUNCTION(Runtime_NewObjectFromBound) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
// First argument is a function to use as a constructor.
@@ -8319,27 +8342,22 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObjectFromBound) {
}
if (!bound_function->IsJSFunction()) {
- bool exception_thrown;
- bound_function = Execution::TryGetConstructorDelegate(isolate,
- bound_function,
- &exception_thrown);
- if (exception_thrown) return Failure::Exception();
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, bound_function,
+ Execution::TryGetConstructorDelegate(isolate, bound_function));
}
ASSERT(bound_function->IsJSFunction());
- bool exception = false;
- Handle<Object> result =
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
Execution::New(Handle<JSFunction>::cast(bound_function),
- total_argc, param_data.get(), &exception);
- if (exception) {
- return Failure::Exception();
- }
- ASSERT(!result.is_null());
+ total_argc, param_data.get()));
return *result;
}
-static MaybeObject* Runtime_NewObjectHelper(Isolate* isolate,
+static Object* Runtime_NewObjectHelper(Isolate* isolate,
Handle<Object> constructor,
Handle<AllocationSite> site) {
// If the constructor isn't a proper function we throw a type error.
@@ -8361,13 +8379,11 @@ static MaybeObject* Runtime_NewObjectHelper(Isolate* isolate,
return isolate->Throw(*type_error);
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
Debug* debug = isolate->debug();
// Handle stepping into constructors if step into is active.
if (debug->StepInActive()) {
debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
}
-#endif
if (function->has_initial_map()) {
if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
@@ -8405,7 +8421,6 @@ static MaybeObject* Runtime_NewObjectHelper(Isolate* isolate,
} else {
result = isolate->factory()->NewJSObjectWithMemento(function, site);
}
- RETURN_IF_EMPTY_HANDLE(isolate, result);
isolate->counters()->constructed_objects()->Increment();
isolate->counters()->constructed_objects_runtime()->Increment();
@@ -8414,35 +8429,31 @@ static MaybeObject* Runtime_NewObjectHelper(Isolate* isolate,
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NewObject) {
+RUNTIME_FUNCTION(RuntimeHidden_NewObject) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
-
- Handle<Object> constructor = args.at<Object>(0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
return Runtime_NewObjectHelper(isolate,
constructor,
Handle<AllocationSite>::null());
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NewObjectWithAllocationSite) {
+RUNTIME_FUNCTION(RuntimeHidden_NewObjectWithAllocationSite) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
-
- Handle<Object> constructor = args.at<Object>(1);
- Handle<Object> feedback = args.at<Object>(0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, feedback, 0);
Handle<AllocationSite> site;
if (feedback->IsAllocationSite()) {
// The feedback can be an AllocationSite or undefined.
site = Handle<AllocationSite>::cast(feedback);
}
- return Runtime_NewObjectHelper(isolate,
- constructor,
- site);
+ return Runtime_NewObjectHelper(isolate, constructor, site);
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_FinalizeInstanceSize) {
+RUNTIME_FUNCTION(RuntimeHidden_FinalizeInstanceSize) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
@@ -8453,11 +8464,10 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_FinalizeInstanceSize) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_CompileUnoptimized) {
+RUNTIME_FUNCTION(RuntimeHidden_CompileUnoptimized) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
-
- Handle<JSFunction> function = args.at<JSFunction>(0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
#ifdef DEBUG
if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
PrintF("[unoptimized: ");
@@ -8469,8 +8479,9 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_CompileUnoptimized) {
// Compile the target function.
ASSERT(function->shared()->allows_lazy_compilation());
- Handle<Code> code = Compiler::GetUnoptimizedCode(function);
- RETURN_IF_EMPTY_HANDLE(isolate, code);
+ Handle<Code> code;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
+ Compiler::GetUnoptimizedCode(function));
function->ReplaceCode(*code);
// All done. Return the compiled code.
@@ -8482,10 +8493,10 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_CompileUnoptimized) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_CompileOptimized) {
+RUNTIME_FUNCTION(RuntimeHidden_CompileOptimized) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- Handle<JSFunction> function = args.at<JSFunction>(0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1);
Handle<Code> unoptimized(function->shared()->code());
@@ -8511,8 +8522,13 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_CompileOptimized) {
} else {
Compiler::ConcurrencyMode mode = concurrent ? Compiler::CONCURRENT
: Compiler::NOT_CONCURRENT;
- Handle<Code> code = Compiler::GetOptimizedCode(function, unoptimized, mode);
- function->ReplaceCode(code.is_null() ? *unoptimized : *code);
+ Handle<Code> code;
+ if (Compiler::GetOptimizedCode(
+ function, unoptimized, mode).ToHandle(&code)) {
+ function->ReplaceCode(*code);
+ } else {
+ function->ReplaceCode(*unoptimized);
+ }
}
ASSERT(function->code()->kind() == Code::FUNCTION ||
@@ -8545,7 +8561,7 @@ class ActivationsFinder : public ThreadVisitor {
};
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NotifyStubFailure) {
+RUNTIME_FUNCTION(RuntimeHidden_NotifyStubFailure) {
HandleScope scope(isolate);
ASSERT(args.length() == 0);
Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
@@ -8555,12 +8571,12 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NotifyStubFailure) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NotifyDeoptimized) {
+RUNTIME_FUNCTION(RuntimeHidden_NotifyDeoptimized) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- RUNTIME_ASSERT(args[0]->IsSmi());
+ CONVERT_SMI_ARG_CHECKED(type_arg, 0);
Deoptimizer::BailoutType type =
- static_cast<Deoptimizer::BailoutType>(args.smi_at(0));
+ static_cast<Deoptimizer::BailoutType>(type_arg);
Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
ASSERT(AllowHeapAllocation::IsAllowed());
@@ -8614,7 +8630,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NotifyDeoptimized) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DeoptimizeFunction) {
+RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
@@ -8626,21 +8642,22 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeoptimizeFunction) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearFunctionTypeFeedback) {
+RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+ function->shared()->ClearTypeFeedbackInfo();
Code* unoptimized = function->shared()->code();
if (unoptimized->kind() == Code::FUNCTION) {
unoptimized->ClearInlineCaches();
- unoptimized->ClearTypeFeedbackInfo(isolate->heap());
}
return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_RunningInSimulator) {
+RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 0);
#if defined(USE_SIMULATOR)
return isolate->heap()->true_value();
#else
@@ -8649,14 +8666,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RunningInSimulator) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsConcurrentRecompilationSupported) {
- HandleScope scope(isolate);
- return isolate->concurrent_recompilation_enabled()
- ? isolate->heap()->true_value() : isolate->heap()->false_value();
+RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
+ SealHandleScope shs(isolate);
+ ASSERT(args.length() == 0);
+ return isolate->heap()->ToBoolean(
+ isolate->concurrent_recompilation_enabled());
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
+RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
HandleScope scope(isolate);
RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
@@ -8691,7 +8709,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NeverOptimizeFunction) {
+RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, function, 0);
@@ -8700,7 +8718,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NeverOptimizeFunction) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) {
+RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
HandleScope scope(isolate);
RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
if (!isolate->use_crankshaft()) {
@@ -8735,7 +8753,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_UnblockConcurrentRecompilation) {
+RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
+ ASSERT(args.length() == 0);
RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled());
isolate->optimizing_compiler_thread()->Unblock();
@@ -8743,7 +8762,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_UnblockConcurrentRecompilation) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationCount) {
+RUNTIME_FUNCTION(Runtime_GetOptimizationCount) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
@@ -8770,7 +8789,7 @@ static bool IsSuitableForOnStackReplacement(Isolate* isolate,
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
+RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
@@ -8831,15 +8850,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
PrintF(" at AST id %d]\n", ast_id.ToInt());
}
result = Compiler::GetConcurrentlyOptimizedCode(job);
- } else if (result.is_null() &&
- IsSuitableForOnStackReplacement(isolate, function, caller_code)) {
+ } else if (IsSuitableForOnStackReplacement(isolate, function, caller_code)) {
if (FLAG_trace_osr) {
PrintF("[OSR - Compiling: ");
function->PrintName();
PrintF(" at AST id %d]\n", ast_id.ToInt());
}
- result = Compiler::GetOptimizedCode(function, caller_code, mode, ast_id);
- if (result.is_identical_to(isolate->builtins()->InOptimizationQueue())) {
+ MaybeHandle<Code> maybe_result = Compiler::GetOptimizedCode(
+ function, caller_code, mode, ast_id);
+ if (maybe_result.ToHandle(&result) &&
+ result.is_identical_to(isolate->builtins()->InOptimizationQueue())) {
// Optimization is queued. Return to check later.
return NULL;
}
@@ -8883,7 +8903,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAllocationTimeout) {
+RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2 || args.length() == 3);
#ifdef DEBUG
@@ -8905,21 +8925,23 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAllocationTimeout) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) {
+RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 0);
RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetRootNaN) {
+RUNTIME_FUNCTION(Runtime_GetRootNaN) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 0);
RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
return isolate->heap()->nan_value();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Call) {
+RUNTIME_FUNCTION(Runtime_Call) {
HandleScope scope(isolate);
ASSERT(args.length() >= 2);
int argc = args.length() - 2;
@@ -8938,33 +8960,32 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Call) {
}
for (int i = 0; i < argc; ++i) {
- MaybeObject* maybe = args[1 + i];
- Object* object;
- if (!maybe->To<Object>(&object)) return maybe;
- argv[i] = Handle<Object>(object, isolate);
+ argv[i] = Handle<Object>(args[1 + i], isolate);
}
- bool threw;
Handle<JSReceiver> hfun(fun);
Handle<Object> hreceiver(receiver, isolate);
- Handle<Object> result = Execution::Call(
- isolate, hfun, hreceiver, argc, argv, &threw, true);
-
- if (threw) return Failure::Exception();
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Execution::Call(isolate, hfun, hreceiver, argc, argv, true));
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Apply) {
+RUNTIME_FUNCTION(Runtime_Apply) {
HandleScope scope(isolate);
ASSERT(args.length() == 5);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
- Handle<Object> receiver = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
CONVERT_SMI_ARG_CHECKED(offset, 3);
CONVERT_SMI_ARG_CHECKED(argc, 4);
RUNTIME_ASSERT(offset >= 0);
- RUNTIME_ASSERT(argc >= 0);
+ // Loose upper bound to allow fuzzing. We'll most likely run out of
+ // stack space before hitting this limit.
+ static int kMaxArgc = 1000000;
+ RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
// If there are too many arguments, allocate argv via malloc.
const int argv_small_size = 10;
@@ -8978,167 +8999,152 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Apply) {
}
for (int i = 0; i < argc; ++i) {
- argv[i] = Object::GetElement(isolate, arguments, offset + i);
- RETURN_IF_EMPTY_HANDLE(isolate, argv[i]);
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, argv[i],
+ Object::GetElement(isolate, arguments, offset + i));
}
- bool threw;
- Handle<Object> result = Execution::Call(
- isolate, fun, receiver, argc, argv, &threw, true);
-
- if (threw) return Failure::Exception();
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Execution::Call(isolate, fun, receiver, argc, argv, true));
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionDelegate) {
+RUNTIME_FUNCTION(Runtime_GetFunctionDelegate) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- RUNTIME_ASSERT(!args[0]->IsJSFunction());
- return *Execution::GetFunctionDelegate(isolate, args.at<Object>(0));
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+ RUNTIME_ASSERT(!object->IsJSFunction());
+ return *Execution::GetFunctionDelegate(isolate, object);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructorDelegate) {
+RUNTIME_FUNCTION(Runtime_GetConstructorDelegate) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- RUNTIME_ASSERT(!args[0]->IsJSFunction());
- return *Execution::GetConstructorDelegate(isolate, args.at<Object>(0));
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+ RUNTIME_ASSERT(!object->IsJSFunction());
+ return *Execution::GetConstructorDelegate(isolate, object);
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NewGlobalContext) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(RuntimeHidden_NewGlobalContext) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSFunction, function, 0);
- CONVERT_ARG_CHECKED(ScopeInfo, scope_info, 1);
- Context* result;
- MaybeObject* maybe_result =
- isolate->heap()->AllocateGlobalContext(function, scope_info);
- if (!maybe_result->To(&result)) return maybe_result;
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+ CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
+ Handle<Context> result =
+ isolate->factory()->NewGlobalContext(function, scope_info);
ASSERT(function->context() == isolate->context());
ASSERT(function->context()->global_object() == result->global_object());
- result->global_object()->set_global_context(result);
-
- return result; // non-failure
+ result->global_object()->set_global_context(*result);
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NewFunctionContext) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(RuntimeHidden_NewFunctionContext) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSFunction, function, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
int length = function->shared()->scope_info()->ContextLength();
- return isolate->heap()->AllocateFunctionContext(length, function);
+ return *isolate->factory()->NewFunctionContext(length, function);
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_PushWithContext) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(RuntimeHidden_PushWithContext) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
- JSReceiver* extension_object;
+ Handle<JSReceiver> extension_object;
if (args[0]->IsJSReceiver()) {
- extension_object = JSReceiver::cast(args[0]);
+ extension_object = args.at<JSReceiver>(0);
} else {
- // Convert the object to a proper JavaScript object.
- MaybeObject* maybe_js_object = args[0]->ToObject(isolate);
- if (!maybe_js_object->To(&extension_object)) {
- if (Failure::cast(maybe_js_object)->IsInternalError()) {
- HandleScope scope(isolate);
- Handle<Object> handle = args.at<Object>(0);
- Handle<Object> result =
- isolate->factory()->NewTypeError("with_expression",
- HandleVector(&handle, 1));
- return isolate->Throw(*result);
- } else {
- return maybe_js_object;
- }
+ // Try to convert the object to a proper JavaScript object.
+ MaybeHandle<JSReceiver> maybe_object =
+ Object::ToObject(isolate, args.at<Object>(0));
+ if (!maybe_object.ToHandle(&extension_object)) {
+ Handle<Object> handle = args.at<Object>(0);
+ Handle<Object> result =
+ isolate->factory()->NewTypeError("with_expression",
+ HandleVector(&handle, 1));
+ return isolate->Throw(*result);
}
}
- JSFunction* function;
+ Handle<JSFunction> function;
if (args[1]->IsSmi()) {
// A smi sentinel indicates a context nested inside global code rather
// than some function. There is a canonical empty function that can be
// gotten from the native context.
- function = isolate->context()->native_context()->closure();
+ function = handle(isolate->context()->native_context()->closure());
} else {
- function = JSFunction::cast(args[1]);
+ function = args.at<JSFunction>(1);
}
- Context* context;
- MaybeObject* maybe_context =
- isolate->heap()->AllocateWithContext(function,
- isolate->context(),
- extension_object);
- if (!maybe_context->To(&context)) return maybe_context;
- isolate->set_context(context);
- return context;
+ Handle<Context> current(isolate->context());
+ Handle<Context> context = isolate->factory()->NewWithContext(
+ function, current, extension_object);
+ isolate->set_context(*context);
+ return *context;
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_PushCatchContext) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(RuntimeHidden_PushCatchContext) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 3);
- String* name = String::cast(args[0]);
- Object* thrown_object = args[1];
- JSFunction* function;
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1);
+ Handle<JSFunction> function;
if (args[2]->IsSmi()) {
// A smi sentinel indicates a context nested inside global code rather
// than some function. There is a canonical empty function that can be
// gotten from the native context.
- function = isolate->context()->native_context()->closure();
+ function = handle(isolate->context()->native_context()->closure());
} else {
- function = JSFunction::cast(args[2]);
+ function = args.at<JSFunction>(2);
}
- Context* context;
- MaybeObject* maybe_context =
- isolate->heap()->AllocateCatchContext(function,
- isolate->context(),
- name,
- thrown_object);
- if (!maybe_context->To(&context)) return maybe_context;
- isolate->set_context(context);
- return context;
+ Handle<Context> current(isolate->context());
+ Handle<Context> context = isolate->factory()->NewCatchContext(
+ function, current, name, thrown_object);
+ isolate->set_context(*context);
+ return *context;
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_PushBlockContext) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(RuntimeHidden_PushBlockContext) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
- ScopeInfo* scope_info = ScopeInfo::cast(args[0]);
- JSFunction* function;
+ CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
+ Handle<JSFunction> function;
if (args[1]->IsSmi()) {
// A smi sentinel indicates a context nested inside global code rather
// than some function. There is a canonical empty function that can be
// gotten from the native context.
- function = isolate->context()->native_context()->closure();
+ function = handle(isolate->context()->native_context()->closure());
} else {
- function = JSFunction::cast(args[1]);
+ function = args.at<JSFunction>(1);
}
- Context* context;
- MaybeObject* maybe_context =
- isolate->heap()->AllocateBlockContext(function,
- isolate->context(),
- scope_info);
- if (!maybe_context->To(&context)) return maybe_context;
- isolate->set_context(context);
- return context;
+ Handle<Context> current(isolate->context());
+ Handle<Context> context = isolate->factory()->NewBlockContext(
+ function, current, scope_info);
+ isolate->set_context(*context);
+ return *context;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSModule) {
+RUNTIME_FUNCTION(Runtime_IsJSModule) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
- Object* obj = args[0];
+ CONVERT_ARG_CHECKED(Object, obj, 0);
return isolate->heap()->ToBoolean(obj->IsJSModule());
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_PushModuleContext) {
+RUNTIME_FUNCTION(RuntimeHidden_PushModuleContext) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(index, 0);
@@ -9173,7 +9179,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_PushModuleContext) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeclareModules) {
+RUNTIME_FUNCTION(RuntimeHidden_DeclareModules) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0);
@@ -9198,15 +9204,16 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeclareModules) {
IsImmutableVariableMode(mode) ? FROZEN : SEALED;
Handle<AccessorInfo> info =
Accessors::MakeModuleExport(name, index, attr);
- Handle<Object> result = JSObject::SetAccessor(module, info);
- ASSERT(!(result.is_null() || result->IsUndefined()));
+ Handle<Object> result =
+ JSObject::SetAccessor(module, info).ToHandleChecked();
+ ASSERT(!result->IsUndefined());
USE(result);
break;
}
case MODULE: {
Object* referenced_context = Context::cast(host_context)->get(index);
Handle<JSModule> value(Context::cast(referenced_context)->module());
- JSReceiver::SetProperty(module, name, value, FROZEN, STRICT);
+ JSReceiver::SetProperty(module, name, value, FROZEN, STRICT).Assert();
break;
}
case INTERNAL:
@@ -9218,7 +9225,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeclareModules) {
}
}
- JSObject::PreventExtensions(module);
+ JSObject::PreventExtensions(module).Assert();
}
ASSERT(!isolate->has_pending_exception());
@@ -9226,7 +9233,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeclareModules) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeleteContextSlot) {
+RUNTIME_FUNCTION(RuntimeHidden_DeleteContextSlot) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -9257,8 +9264,10 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeleteContextSlot) {
// the global object, or the subject of a with. Try to delete it
// (respecting DONT_DELETE).
Handle<JSObject> object = Handle<JSObject>::cast(holder);
- Handle<Object> result = JSReceiver::DeleteProperty(object, name);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ JSReceiver::DeleteProperty(object, name));
return *result;
}
@@ -9273,12 +9282,12 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_DeleteContextSlot) {
// allocated by the caller, and passed as a pointer in a hidden first parameter.
#ifdef V8_HOST_ARCH_64_BIT
struct ObjectPair {
- MaybeObject* x;
- MaybeObject* y;
+ Object* x;
+ Object* y;
};
-static inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) {
+static inline ObjectPair MakePair(Object* x, Object* y) {
ObjectPair result = {x, y};
// Pointers x and y returned in rax and rdx, in AMD-x64-abi.
// In Win64 they are assigned to a hidden first argument.
@@ -9286,20 +9295,18 @@ static inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) {
}
#else
typedef uint64_t ObjectPair;
-static inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) {
+static inline ObjectPair MakePair(Object* x, Object* y) {
+#if defined(V8_TARGET_LITTLE_ENDIAN)
return reinterpret_cast<uint32_t>(x) |
(reinterpret_cast<ObjectPair>(y) << 32);
-}
+#elif defined(V8_TARGET_BIG_ENDIAN)
+ return reinterpret_cast<uint32_t>(y) |
+ (reinterpret_cast<ObjectPair>(x) << 32);
+#else
+#error Unknown endianness
#endif
-
-
-static inline MaybeObject* Unhole(Heap* heap,
- MaybeObject* x,
- PropertyAttributes attributes) {
- ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0);
- USE(attributes);
- return x->IsTheHole() ? heap->undefined_value() : x;
}
+#endif
static Object* ComputeReceiverForNonGlobal(Isolate* isolate,
@@ -9344,7 +9351,7 @@ static ObjectPair LoadContextSlotHelper(Arguments args,
&attributes,
&binding_flags);
if (isolate->has_pending_exception()) {
- return MakePair(Failure::Exception(), NULL);
+ return MakePair(isolate->heap()->exception(), NULL);
}
// If the index is non-negative, the slot has been found in a context.
@@ -9371,7 +9378,11 @@ static ObjectPair LoadContextSlotHelper(Arguments args,
ASSERT(!value->IsTheHole());
return MakePair(value, *receiver);
case IMMUTABLE_CHECK_INITIALIZED:
- return MakePair(Unhole(isolate->heap(), value, attributes), *receiver);
+ if (value->IsTheHole()) {
+ ASSERT((attributes & READ_ONLY) != 0);
+ value = isolate->heap()->undefined_value();
+ }
+ return MakePair(value, *receiver);
case MISSING_BINDING:
UNREACHABLE();
return MakePair(NULL, NULL);
@@ -9394,8 +9405,12 @@ static ObjectPair LoadContextSlotHelper(Arguments args,
// No need to unhole the value here. This is taken care of by the
// GetProperty function.
- MaybeObject* value = object->GetProperty(*name);
- return MakePair(value, *receiver_handle);
+ Handle<Object> value;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, value,
+ Object::GetProperty(object, name),
+ MakePair(isolate->heap()->exception(), NULL));
+ return MakePair(*value, *receiver_handle);
}
if (throw_error) {
@@ -9412,21 +9427,21 @@ static ObjectPair LoadContextSlotHelper(Arguments args,
}
-RUNTIME_FUNCTION(ObjectPair, RuntimeHidden_LoadContextSlot) {
+RUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_LoadContextSlot) {
return LoadContextSlotHelper(args, isolate, true);
}
-RUNTIME_FUNCTION(ObjectPair, RuntimeHidden_LoadContextSlotNoReferenceError) {
+RUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_LoadContextSlotNoReferenceError) {
return LoadContextSlotHelper(args, isolate, false);
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_StoreContextSlot) {
+RUNTIME_FUNCTION(RuntimeHidden_StoreContextSlot) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
- Handle<Object> value(args[0], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 3);
@@ -9440,7 +9455,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_StoreContextSlot) {
&index,
&attributes,
&binding_flags);
- if (isolate->has_pending_exception()) return Failure::Exception();
+ if (isolate->has_pending_exception()) return isolate->heap()->exception();
if (index >= 0) {
// The property was found in a context slot.
@@ -9493,7 +9508,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_StoreContextSlot) {
// Set the property if it's not read only or doesn't yet exist.
if ((attributes & READ_ONLY) == 0 ||
(JSReceiver::GetLocalPropertyAttribute(object, name) == ABSENT)) {
- RETURN_IF_EMPTY_HANDLE(
+ RETURN_FAILURE_ON_EXCEPTION(
isolate,
JSReceiver::SetProperty(object, name, value, NONE, strict_mode));
} else if (strict_mode == STRICT && (attributes & READ_ONLY) != 0) {
@@ -9507,7 +9522,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_StoreContextSlot) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_Throw) {
+RUNTIME_FUNCTION(RuntimeHidden_Throw) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
@@ -9515,7 +9530,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_Throw) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_ReThrow) {
+RUNTIME_FUNCTION(RuntimeHidden_ReThrow) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
@@ -9523,18 +9538,17 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_ReThrow) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_PromoteScheduledException) {
+RUNTIME_FUNCTION(RuntimeHidden_PromoteScheduledException) {
SealHandleScope shs(isolate);
- ASSERT_EQ(0, args.length());
+ ASSERT(args.length() == 0);
return isolate->PromoteScheduledException();
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_ThrowReferenceError) {
+RUNTIME_FUNCTION(RuntimeHidden_ThrowReferenceError) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
-
- Handle<Object> name(args[0], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
Handle<Object> reference_error =
isolate->factory()->NewReferenceError("not_defined",
HandleVector(&name, 1));
@@ -9542,7 +9556,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_ThrowReferenceError) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_ThrowNotDateError) {
+RUNTIME_FUNCTION(RuntimeHidden_ThrowNotDateError) {
HandleScope scope(isolate);
ASSERT(args.length() == 0);
return isolate->Throw(*isolate->factory()->NewTypeError(
@@ -9550,20 +9564,19 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_ThrowNotDateError) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_ThrowMessage) {
+RUNTIME_FUNCTION(RuntimeHidden_ThrowMessage) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_SMI_ARG_CHECKED(message_id, 0);
const char* message = GetBailoutReason(
static_cast<BailoutReason>(message_id));
Handle<String> message_handle =
- isolate->factory()->NewStringFromAscii(CStrVector(message));
- RETURN_IF_EMPTY_HANDLE(isolate, message_handle);
+ isolate->factory()->NewStringFromAsciiChecked(message);
return isolate->Throw(*message_handle);
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_StackGuard) {
+RUNTIME_FUNCTION(RuntimeHidden_StackGuard) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 0);
@@ -9576,7 +9589,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_StackGuard) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_TryInstallOptimizedCode) {
+RUNTIME_FUNCTION(RuntimeHidden_TryInstallOptimizedCode) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
@@ -9593,7 +9606,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_TryInstallOptimizedCode) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_Interrupt) {
+RUNTIME_FUNCTION(RuntimeHidden_Interrupt) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 0);
return Execution::HandleStackGuardInterrupt(isolate);
@@ -9629,7 +9642,7 @@ static void PrintTransition(Isolate* isolate, Object* result) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceEnter) {
+RUNTIME_FUNCTION(Runtime_TraceEnter) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 0);
PrintTransition(isolate, NULL);
@@ -9637,14 +9650,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceEnter) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceExit) {
+RUNTIME_FUNCTION(Runtime_TraceExit) {
SealHandleScope shs(isolate);
- PrintTransition(isolate, args[0]);
- return args[0]; // return TOS
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ PrintTransition(isolate, obj);
+ return obj; // return TOS
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrint) {
+RUNTIME_FUNCTION(Runtime_DebugPrint) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
@@ -9675,7 +9690,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrint) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugTrace) {
+RUNTIME_FUNCTION(Runtime_DebugTrace) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 0);
isolate->PrintStack(stdout);
@@ -9683,8 +9698,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugTrace) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DateCurrentTime) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_DateCurrentTime) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 0);
// According to ECMA-262, section 15.9.1, page 117, the precision of
@@ -9692,36 +9707,35 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateCurrentTime) {
// time is milliseconds. Therefore, we floor the result of getting
// the OS time.
double millis = std::floor(OS::TimeCurrentMillis());
- return isolate->heap()->NumberFromDouble(millis);
+ return *isolate->factory()->NewNumber(millis);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) {
+RUNTIME_FUNCTION(Runtime_DateParseString) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
-
CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
- FlattenString(str);
-
CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
+ RUNTIME_ASSERT(output->HasFastElements());
JSObject::EnsureCanContainHeapObjectElements(output);
RUNTIME_ASSERT(output->HasFastObjectElements());
+ Handle<FixedArray> output_array(FixedArray::cast(output->elements()));
+ RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
+ str = String::Flatten(str);
DisallowHeapAllocation no_gc;
- FixedArray* output_array = FixedArray::cast(output->elements());
- RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
bool result;
String::FlatContent str_content = str->GetFlatContent();
if (str_content.IsAscii()) {
result = DateParser::Parse(str_content.ToOneByteVector(),
- output_array,
+ *output_array,
isolate->unicode_cache());
} else {
ASSERT(str_content.IsTwoByte());
result = DateParser::Parse(str_content.ToUC16Vector(),
- output_array,
+ *output_array,
isolate->unicode_cache());
}
@@ -9733,29 +9747,31 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DateLocalTimezone) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_DateLocalTimezone) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
const char* zone =
isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x));
- return isolate->heap()->AllocateStringFromUtf8(CStrVector(zone));
+ Handle<String> result = isolate->factory()->NewStringFromUtf8(
+ CStrVector(zone)).ToHandleChecked();
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DateToUTC) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_DateToUTC) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
- return isolate->heap()->NumberFromDouble(static_cast<double>(time));
+ return *isolate->factory()->NewNumber(static_cast<double>(time));
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DateCacheVersion) {
+RUNTIME_FUNCTION(Runtime_DateCacheVersion) {
HandleScope hs(isolate);
ASSERT(args.length() == 0);
if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
@@ -9776,43 +9792,37 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateCacheVersion) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalReceiver) {
+RUNTIME_FUNCTION(Runtime_GlobalReceiver) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
- Object* global = args[0];
+ CONVERT_ARG_CHECKED(Object, global, 0);
if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
return JSGlobalObject::cast(global)->global_receiver();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsAttachedGlobal) {
+RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
- Object* global = args[0];
+ CONVERT_ARG_CHECKED(Object, global, 0);
if (!global->IsJSGlobalObject()) return isolate->heap()->false_value();
return isolate->heap()->ToBoolean(
!JSGlobalObject::cast(global)->IsDetached());
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) {
+RUNTIME_FUNCTION(Runtime_ParseJson) {
HandleScope scope(isolate);
- ASSERT_EQ(1, args.length());
+ ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
- source = Handle<String>(FlattenGetString(source));
+ source = String::Flatten(source);
// Optimized fast case where we only have ASCII characters.
Handle<Object> result;
- if (source->IsSeqOneByteString()) {
- result = JsonParser<true>::Parse(source);
- } else {
- result = JsonParser<false>::Parse(source);
- }
- if (result.is_null()) {
- // Syntax error or stack overflow in scanner.
- ASSERT(isolate->has_pending_exception());
- return Failure::Exception();
- }
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ source->IsSeqOneByteString() ? JsonParser<true>::Parse(source)
+ : JsonParser<false>::Parse(source));
return *result;
}
@@ -9834,9 +9844,9 @@ bool CodeGenerationFromStringsAllowed(Isolate* isolate,
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
+RUNTIME_FUNCTION(Runtime_CompileString) {
HandleScope scope(isolate);
- ASSERT_EQ(2, args.length());
+ ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
@@ -9856,9 +9866,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
// Compile source string in the native context.
ParseRestriction restriction = function_literal_only
? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
- Handle<JSFunction> fun = Compiler::GetFunctionFromEval(
- source, context, SLOPPY, restriction, RelocInfo::kNoPosition);
- RETURN_IF_EMPTY_HANDLE(isolate, fun);
+ Handle<JSFunction> fun;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, fun,
+ Compiler::GetFunctionFromEval(
+ source, context, SLOPPY, restriction, RelocInfo::kNoPosition));
return *fun;
}
@@ -9879,21 +9891,23 @@ static ObjectPair CompileGlobalEval(Isolate* isolate,
native_context->ErrorMessageForCodeGenerationFromStrings();
isolate->Throw(*isolate->factory()->NewEvalError(
"code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
- return MakePair(Failure::Exception(), NULL);
+ return MakePair(isolate->heap()->exception(), NULL);
}
// Deal with a normal eval call with a string argument. Compile it
// and return the compiled function bound in the local context.
static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
- Handle<JSFunction> compiled = Compiler::GetFunctionFromEval(
- source, context, strict_mode, restriction, scope_position);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, compiled,
- MakePair(Failure::Exception(), NULL));
+ Handle<JSFunction> compiled;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, compiled,
+ Compiler::GetFunctionFromEval(
+ source, context, strict_mode, restriction, scope_position),
+ MakePair(isolate->heap()->exception(), NULL));
return MakePair(*compiled, *receiver);
}
-RUNTIME_FUNCTION(ObjectPair, RuntimeHidden_ResolvePossiblyDirectEval) {
+RUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_ResolvePossiblyDirectEval) {
HandleScope scope(isolate);
ASSERT(args.length() == 5);
@@ -9921,52 +9935,35 @@ RUNTIME_FUNCTION(ObjectPair, RuntimeHidden_ResolvePossiblyDirectEval) {
}
-// Allocate a block of memory in the given space (filled with a filler).
-// Used as a fall-back for generated code when the space is full.
-static MaybeObject* Allocate(Isolate* isolate,
- int size,
- bool double_align,
- AllocationSpace space) {
- Heap* heap = isolate->heap();
+RUNTIME_FUNCTION(RuntimeHidden_AllocateInNewSpace) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_SMI_ARG_CHECKED(size, 0);
RUNTIME_ASSERT(IsAligned(size, kPointerSize));
RUNTIME_ASSERT(size > 0);
RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
- HeapObject* allocation;
- { MaybeObject* maybe_allocation = heap->AllocateRaw(size, space, space);
- if (!maybe_allocation->To(&allocation)) return maybe_allocation;
- }
-#ifdef DEBUG
- MemoryChunk* chunk = MemoryChunk::FromAddress(allocation->address());
- ASSERT(chunk->owner()->identity() == space);
-#endif
- heap->CreateFillerObjectAt(allocation->address(), size);
- return allocation;
+ return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_AllocateInNewSpace) {
- SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
- CONVERT_SMI_ARG_CHECKED(size, 0);
- return Allocate(isolate, size, false, NEW_SPACE);
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_AllocateInTargetSpace) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(RuntimeHidden_AllocateInTargetSpace) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(size, 0);
CONVERT_SMI_ARG_CHECKED(flags, 1);
+ RUNTIME_ASSERT(IsAligned(size, kPointerSize));
+ RUNTIME_ASSERT(size > 0);
+ RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
bool double_align = AllocateDoubleAlignFlag::decode(flags);
AllocationSpace space = AllocateTargetSpace::decode(flags);
- return Allocate(isolate, size, double_align, space);
+ return *isolate->factory()->NewFillerObject(size, double_align, space);
}
// Push an object unto an array of objects if it is not already in the
// array. Returns true if the element was pushed on the stack and
// false otherwise.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
+RUNTIME_FUNCTION(Runtime_PushIfAbsent) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
@@ -9979,10 +9976,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
}
// Strict not needed. Used for cycle detection in Array join implementation.
- RETURN_IF_EMPTY_HANDLE(isolate, JSObject::SetFastElement(array, length,
- element,
- SLOPPY,
- true));
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ JSObject::SetFastElement(array, length, element, SLOPPY, true));
return isolate->heap()->true_value();
}
@@ -10037,7 +10033,7 @@ class ArrayConcatVisitor {
Handle<SeededNumberDictionary> dict(
SeededNumberDictionary::cast(*storage_));
Handle<SeededNumberDictionary> result =
- isolate_->factory()->DictionaryAtNumberPut(dict, index, elm);
+ SeededNumberDictionary::AtNumberPut(dict, index, elm);
if (!result.is_identical_to(dict)) {
// Dictionary needed to grow.
clear_storage();
@@ -10061,12 +10057,9 @@ class ArrayConcatVisitor {
Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
Handle<Object> length =
isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
- Handle<Map> map;
- if (fast_elements_) {
- map = JSObject::GetElementsTransitionMap(array, FAST_HOLEY_ELEMENTS);
- } else {
- map = JSObject::GetElementsTransitionMap(array, DICTIONARY_ELEMENTS);
- }
+ Handle<Map> map = JSObject::GetElementsTransitionMap(
+ array,
+ fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
array->set_map(*map);
array->set_length(*length);
array->set_elements(*storage_);
@@ -10079,15 +10072,14 @@ class ArrayConcatVisitor {
ASSERT(fast_elements_);
Handle<FixedArray> current_storage(*storage_);
Handle<SeededNumberDictionary> slow_storage(
- isolate_->factory()->NewSeededNumberDictionary(
- current_storage->length()));
+ SeededNumberDictionary::New(isolate_, current_storage->length()));
uint32_t current_length = static_cast<uint32_t>(current_storage->length());
for (uint32_t i = 0; i < current_length; i++) {
HandleScope loop_scope(isolate_);
Handle<Object> element(current_storage->get(i), isolate_);
if (!element->IsTheHole()) {
Handle<SeededNumberDictionary> new_storage =
- isolate_->factory()->DictionaryAtNumberPut(slow_storage, i, element);
+ SeededNumberDictionary::AtNumberPut(slow_storage, i, element);
if (!new_storage.is_identical_to(slow_storage)) {
slow_storage = loop_scope.CloseAndEscape(new_storage);
}
@@ -10349,8 +10341,10 @@ static bool IterateElements(Isolate* isolate,
} else if (JSReceiver::HasElement(receiver, j)) {
// Call GetElement on receiver, not its prototype, or getters won't
// have the correct receiver.
- element_value = Object::GetElement(isolate, receiver, j);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false);
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, element_value,
+ Object::GetElement(isolate, receiver, j),
+ false);
visitor->visit(j, element_value);
}
}
@@ -10358,6 +10352,8 @@ static bool IterateElements(Isolate* isolate,
}
case FAST_HOLEY_DOUBLE_ELEMENTS:
case FAST_DOUBLE_ELEMENTS: {
+ // Empty array is FixedArray but not FixedDoubleArray.
+ if (length == 0) break;
// Run through the elements FixedArray and use HasElement and GetElement
// to check the prototype for missing elements.
Handle<FixedDoubleArray> elements(
@@ -10374,9 +10370,11 @@ static bool IterateElements(Isolate* isolate,
} else if (JSReceiver::HasElement(receiver, j)) {
// Call GetElement on receiver, not its prototype, or getters won't
// have the correct receiver.
- Handle<Object> element_value =
- Object::GetElement(isolate, receiver, j);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false);
+ Handle<Object> element_value;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, element_value,
+ Object::GetElement(isolate, receiver, j),
+ false);
visitor->visit(j, element_value);
}
}
@@ -10394,8 +10392,11 @@ static bool IterateElements(Isolate* isolate,
while (j < n) {
HandleScope loop_scope(isolate);
uint32_t index = indices[j];
- Handle<Object> element = Object::GetElement(isolate, receiver, index);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element, false);
+ Handle<Object> element;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, element,
+ Object::GetElement(isolate, receiver, index),
+ false);
visitor->visit(index, element);
// Skip to next different index (i.e., omit duplicates).
do {
@@ -10468,7 +10469,7 @@ static bool IterateElements(Isolate* isolate,
* TODO(581): Fix non-compliance for very large concatenations and update to
* following the ECMAScript 5 specification.
*/
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) {
+RUNTIME_FUNCTION(Runtime_ArrayConcat) {
HandleScope handle_scope(isolate);
ASSERT(args.length() == 1);
@@ -10535,12 +10536,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) {
// dictionary.
bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
- Handle<FixedArray> storage;
- if (fast_case) {
- if (kind == FAST_DOUBLE_ELEMENTS) {
+ if (fast_case && kind == FAST_DOUBLE_ELEMENTS) {
+ Handle<FixedArrayBase> storage =
+ isolate->factory()->NewFixedDoubleArray(estimate_result_length);
+ int j = 0;
+ if (estimate_result_length > 0) {
Handle<FixedDoubleArray> double_storage =
- isolate->factory()->NewFixedDoubleArray(estimate_result_length);
- int j = 0;
+ Handle<FixedDoubleArray>::cast(storage);
bool failure = false;
for (int i = 0; i < argument_count; i++) {
Handle<Object> obj(elements->get(i), isolate);
@@ -10556,8 +10558,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) {
switch (array->map()->elements_kind()) {
case FAST_HOLEY_DOUBLE_ELEMENTS:
case FAST_DOUBLE_ELEMENTS: {
- // Empty fixed array indicates that there are no elements.
- if (array->elements()->IsFixedArray()) break;
+ // Empty array is FixedArray but not FixedDoubleArray.
+ if (length == 0) break;
FixedDoubleArray* elements =
FixedDoubleArray::cast(array->elements());
for (uint32_t i = 0; i < length; i++) {
@@ -10596,15 +10598,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) {
}
if (failure) break;
}
- Handle<JSArray> array = isolate->factory()->NewJSArray(0);
- Smi* length = Smi::FromInt(j);
- Handle<Map> map;
- map = JSObject::GetElementsTransitionMap(array, kind);
- array->set_map(*map);
- array->set_length(length);
- array->set_elements(*double_storage);
- return *array;
}
+ Handle<JSArray> array = isolate->factory()->NewJSArray(0);
+ Smi* length = Smi::FromInt(j);
+ Handle<Map> map;
+ map = JSObject::GetElementsTransitionMap(array, kind);
+ array->set_map(*map);
+ array->set_length(length);
+ array->set_elements(*storage);
+ return *array;
+ }
+
+ Handle<FixedArray> storage;
+ if (fast_case) {
// The backing storage array must have non-existing elements to preserve
// holes across concat operations.
storage = isolate->factory()->NewFixedArrayWithHoles(
@@ -10614,7 +10620,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) {
uint32_t at_least_space_for = estimate_nof_elements +
(estimate_nof_elements >> 2);
storage = Handle<FixedArray>::cast(
- isolate->factory()->NewSeededNumberDictionary(at_least_space_for));
+ SeededNumberDictionary::New(isolate, at_least_space_for));
}
ArrayConcatVisitor visitor(isolate, storage, fast_case);
@@ -10624,7 +10630,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) {
if (obj->IsJSArray()) {
Handle<JSArray> array = Handle<JSArray>::cast(obj);
if (!IterateElements(isolate, array, &visitor)) {
- return Failure::Exception();
+ return isolate->heap()->exception();
}
} else {
visitor.visit(0, obj);
@@ -10643,7 +10649,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) {
// This will not allocate (flatten the string), but it may run
// very slowly for very deeply nested ConsStrings. For debugging use only.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalPrint) {
+RUNTIME_FUNCTION(Runtime_GlobalPrint) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
@@ -10664,7 +10670,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalPrint) {
// property.
// Returns the number of non-undefined elements collected.
// Returns -1 if hole removal is not supported by this method.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_RemoveArrayHoles) {
+RUNTIME_FUNCTION(Runtime_RemoveArrayHoles) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
@@ -10674,33 +10680,30 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RemoveArrayHoles) {
// Move contents of argument 0 (an array) to argument 1 (an array)
-RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_MoveArrayContents) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(JSArray, from, 0);
- CONVERT_ARG_CHECKED(JSArray, to, 1);
- from->ValidateElements();
- to->ValidateElements();
- FixedArrayBase* new_elements = from->elements();
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, from, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, to, 1);
+ JSObject::ValidateElements(from);
+ JSObject::ValidateElements(to);
+
+ Handle<FixedArrayBase> new_elements(from->elements());
ElementsKind from_kind = from->GetElementsKind();
- MaybeObject* maybe_new_map;
- maybe_new_map = to->GetElementsTransitionMap(isolate, from_kind);
- Object* new_map;
- if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
- to->set_map_and_elements(Map::cast(new_map), new_elements);
+ Handle<Map> new_map = JSObject::GetElementsTransitionMap(to, from_kind);
+ JSObject::SetMapAndElements(to, new_map, new_elements);
to->set_length(from->length());
- Object* obj;
- { MaybeObject* maybe_obj = from->ResetElements();
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
+
+ JSObject::ResetElements(from);
from->set_length(Smi::FromInt(0));
- to->ValidateElements();
- return to;
+
+ JSObject::ValidateElements(to);
+ return *to;
}
// How many elements does this object/array have?
-RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) {
+RUNTIME_FUNCTION(Runtime_EstimateNumberOfElements) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSObject, object, 0);
@@ -10721,7 +10724,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) {
// or undefined) or a number representing the positive length of an interval
// starting at index 0.
// Intervals can span over some keys that are not in the object.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
+RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
@@ -10741,7 +10744,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
isolate->factory()->NewFixedArray(
current->NumberOfLocalElements(NONE));
current->GetLocalElementKeys(*current_keys, NONE);
- keys = UnionOfKeys(keys, current_keys);
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, keys, FixedArray::UnionOfKeys(keys, current_keys));
}
// Erase any keys >= length.
// TODO(adamk): Remove this step when the contract of %GetArrayKeys
@@ -10759,7 +10763,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) {
+RUNTIME_FUNCTION(Runtime_LookupAccessor) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
@@ -10767,15 +10771,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) {
CONVERT_SMI_ARG_CHECKED(flag, 2);
AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
- Handle<Object> result =
- JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component));
return *result;
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugBreak) {
+RUNTIME_FUNCTION(Runtime_DebugBreak) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 0);
return Execution::DebugBreakHelper(isolate);
@@ -10798,21 +10802,21 @@ static StackFrame::Id UnwrapFrameId(int wrapped) {
// args[0]: debug event listener function to set or null or undefined for
// clearing the event listener function
// args[1]: object supplied during callback
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDebugEventListener) {
+RUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
RUNTIME_ASSERT(args[0]->IsJSFunction() ||
args[0]->IsUndefined() ||
args[0]->IsNull());
- Handle<Object> callback = args.at<Object>(0);
- Handle<Object> data = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
isolate->debugger()->SetEventListener(callback, data);
return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Break) {
+RUNTIME_FUNCTION(Runtime_Break) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 0);
isolate->stack_guard()->DebugBreak();
@@ -10820,64 +10824,50 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Break) {
}
-static MaybeObject* DebugLookupResultValue(Heap* heap,
- Object* receiver,
- Name* name,
- LookupResult* result,
- bool* caught_exception) {
- Object* value;
+static Handle<Object> DebugLookupResultValue(Isolate* isolate,
+ Handle<Object> receiver,
+ Handle<Name> name,
+ LookupResult* result,
+ bool* has_caught = NULL) {
+ Handle<Object> value = isolate->factory()->undefined_value();
+ if (!result->IsFound()) return value;
switch (result->type()) {
case NORMAL:
- value = result->holder()->GetNormalizedProperty(result);
- if (value->IsTheHole()) {
- return heap->undefined_value();
- }
- return value;
- case FIELD: {
- Object* value;
- MaybeObject* maybe_value =
- JSObject::cast(result->holder())->FastPropertyAt(
- result->representation(),
- result->GetFieldIndex().field_index());
- if (!maybe_value->To(&value)) return maybe_value;
- if (value->IsTheHole()) {
- return heap->undefined_value();
- }
- return value;
- }
+ value = JSObject::GetNormalizedProperty(
+ handle(result->holder(), isolate), result);
+ break;
+ case FIELD:
+ value = JSObject::FastPropertyAt(handle(result->holder(), isolate),
+ result->representation(),
+ result->GetFieldIndex().field_index());
+ break;
case CONSTANT:
- return result->GetConstant();
+ return handle(result->GetConstant(), isolate);
case CALLBACKS: {
- Object* structure = result->GetCallbackObject();
- if (structure->IsForeign() || structure->IsAccessorInfo()) {
- Isolate* isolate = heap->isolate();
- HandleScope scope(isolate);
- Handle<Object> value = JSObject::GetPropertyWithCallback(
- handle(result->holder(), isolate),
- handle(receiver, isolate),
- handle(structure, isolate),
- handle(name, isolate));
- if (value.is_null()) {
- MaybeObject* exception = heap->isolate()->pending_exception();
- heap->isolate()->clear_pending_exception();
- if (caught_exception != NULL) *caught_exception = true;
- return exception;
+ Handle<Object> structure(result->GetCallbackObject(), isolate);
+ ASSERT(!structure->IsForeign());
+ if (structure->IsAccessorInfo()) {
+ MaybeHandle<Object> obj = JSObject::GetPropertyWithCallback(
+ handle(result->holder(), isolate), receiver, structure, name);
+ if (!obj.ToHandle(&value)) {
+ value = handle(isolate->pending_exception(), isolate);
+ isolate->clear_pending_exception();
+ if (has_caught != NULL) *has_caught = true;
+ return value;
}
- return *value;
- } else {
- return heap->undefined_value();
}
+ break;
}
case INTERCEPTOR:
- case TRANSITION:
- return heap->undefined_value();
+ break;
case HANDLER:
case NONEXISTENT:
UNREACHABLE();
- return heap->undefined_value();
+ break;
}
- UNREACHABLE(); // keep the compiler happy
- return heap->undefined_value();
+ ASSERT(!value->IsTheHole() || result->IsReadOnly());
+ return value->IsTheHole()
+ ? Handle<Object>::cast(isolate->factory()->undefined_value()) : value;
}
@@ -10893,7 +10883,7 @@ static MaybeObject* DebugLookupResultValue(Heap* heap,
// 4: Setter function if defined
// Items 2-4 are only filled if the property has either a getter or a setter
// defined through __defineGetter__ and/or __defineSetter__.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
+RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -10924,9 +10914,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
uint32_t index;
if (name->AsArrayIndex(&index)) {
Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
- Handle<Object> element_or_char =
- Runtime::GetElementOrCharAt(isolate, obj, index);
- RETURN_IF_EMPTY_HANDLE(isolate, element_or_char);
+ Handle<Object> element_or_char;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, element_or_char,
+ Runtime::GetElementOrCharAt(isolate, obj, index));
details->set(0, *element_or_char);
details->set(
1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi());
@@ -10940,7 +10931,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
Handle<JSObject> jsproto = obj;
for (int i = 0; i < length; i++) {
LookupResult result(isolate);
- jsproto->LocalLookup(*name, &result);
+ jsproto->LocalLookup(name, &result);
if (result.IsFound()) {
// LookupResult is not GC safe as it holds raw object pointers.
// GC can happen later in this code so put the required fields into
@@ -10950,29 +10941,23 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
result_callback_obj = Handle<Object>(result.GetCallbackObject(),
isolate);
}
- Smi* property_details = result.GetPropertyDetails().AsSmi();
- // DebugLookupResultValue can cause GC so details from LookupResult needs
- // to be copied to handles before this.
- bool caught_exception = false;
- Object* raw_value;
- { MaybeObject* maybe_raw_value =
- DebugLookupResultValue(isolate->heap(), *obj, *name,
- &result, &caught_exception);
- if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value;
- }
- Handle<Object> value(raw_value, isolate);
+
+
+ bool has_caught = false;
+ Handle<Object> value = DebugLookupResultValue(
+ isolate, obj, name, &result, &has_caught);
// If the callback object is a fixed array then it contains JavaScript
// getter and/or setter.
- bool hasJavaScriptAccessors = result.IsPropertyCallbacks() &&
- result_callback_obj->IsAccessorPair();
+ bool has_js_accessors = result.IsPropertyCallbacks() &&
+ result_callback_obj->IsAccessorPair();
Handle<FixedArray> details =
- isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2);
+ isolate->factory()->NewFixedArray(has_js_accessors ? 5 : 2);
details->set(0, *value);
- details->set(1, property_details);
- if (hasJavaScriptAccessors) {
+ details->set(1, result.GetPropertyDetails().AsSmi());
+ if (has_js_accessors) {
AccessorPair* accessors = AccessorPair::cast(*result_callback_obj);
- details->set(2, isolate->heap()->ToBoolean(caught_exception));
+ details->set(2, isolate->heap()->ToBoolean(has_caught));
details->set(3, accessors->GetComponent(ACCESSOR_GETTER));
details->set(4, accessors->GetComponent(ACCESSOR_SETTER));
}
@@ -10988,7 +10973,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetProperty) {
+RUNTIME_FUNCTION(Runtime_DebugGetProperty) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -10997,17 +10982,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetProperty) {
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
LookupResult result(isolate);
- obj->Lookup(*name, &result);
- if (result.IsFound()) {
- return DebugLookupResultValue(isolate->heap(), *obj, *name, &result, NULL);
- }
- return isolate->heap()->undefined_value();
+ obj->Lookup(name, &result);
+ return *DebugLookupResultValue(isolate, obj, name, &result);
}
// Return the property type calculated from the property details.
// args[0]: smi with property details.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyTypeFromDetails) {
+RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
@@ -11017,7 +10999,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyTypeFromDetails) {
// Return the property attribute calculated from the property details.
// args[0]: smi with property details.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyAttributesFromDetails) {
+RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
@@ -11027,7 +11009,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyAttributesFromDetails) {
// Return the property insertion index calculated from the property details.
// args[0]: smi with property details.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyIndexFromDetails) {
+RUNTIME_FUNCTION(Runtime_DebugPropertyIndexFromDetails) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
@@ -11039,7 +11021,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPropertyIndexFromDetails) {
// Return property value from named interceptor.
// args[0]: object
// args[1]: property name
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugNamedInterceptorPropertyValue) {
+RUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
@@ -11047,9 +11029,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugNamedInterceptorPropertyValue) {
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
PropertyAttributes attributes;
- Handle<Object> result =
- JSObject::GetPropertyWithInterceptor(obj, obj, name, &attributes);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ JSObject::GetPropertyWithInterceptor(obj, obj, name, &attributes));
return *result;
}
@@ -11057,43 +11040,39 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugNamedInterceptorPropertyValue) {
// Return element value from indexed interceptor.
// args[0]: object
// args[1]: index
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugIndexedInterceptorElementValue) {
+RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
RUNTIME_ASSERT(obj->HasIndexedInterceptor());
CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
- Handle<Object> result = JSObject::GetElementWithInterceptor(obj, obj, index);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, JSObject::GetElementWithInterceptor(obj, obj, index));
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckExecutionState) {
+static bool CheckExecutionState(Isolate* isolate, int break_id) {
+ return (isolate->debug()->break_id() != 0 &&
+ break_id == isolate->debug()->break_id());
+}
+
+
+RUNTIME_FUNCTION(Runtime_CheckExecutionState) {
SealHandleScope shs(isolate);
- ASSERT(args.length() >= 1);
+ ASSERT(args.length() == 1);
CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
- // Check that the break id is valid.
- if (isolate->debug()->break_id() == 0 ||
- break_id != isolate->debug()->break_id()) {
- return isolate->Throw(
- isolate->heap()->illegal_execution_state_string());
- }
-
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
return isolate->heap()->true_value();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameCount) {
+RUNTIME_FUNCTION(Runtime_GetFrameCount) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
-
- // Check arguments.
- Object* result;
- { MaybeObject* maybe_result = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
// Count all frames which are relevant to debugging stack trace.
int n = 0;
@@ -11227,16 +11206,12 @@ static SaveContext* FindSavedContextForFrame(Isolate* isolate,
// Arguments name, value
// Locals name, value
// Return value if any
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
+RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
Heap* heap = isolate->heap();
@@ -11284,33 +11259,44 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
ASSERT(*scope_info != ScopeInfo::Empty(isolate));
// Get the locals names and values into a temporary array.
- //
- // TODO(1240907): Hide compiler-introduced stack variables
- // (e.g. .result)? For users of the debugger, they will probably be
- // confusing.
+ int local_count = scope_info->LocalCount();
+ for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
+ // Hide compiler-introduced temporary variables, whether on the stack or on
+ // the context.
+ if (scope_info->LocalIsSynthetic(slot))
+ local_count--;
+ }
+
Handle<FixedArray> locals =
- isolate->factory()->NewFixedArray(scope_info->LocalCount() * 2);
+ isolate->factory()->NewFixedArray(local_count * 2);
// Fill in the values of the locals.
+ int local = 0;
int i = 0;
for (; i < scope_info->StackLocalCount(); ++i) {
// Use the value from the stack.
- locals->set(i * 2, scope_info->LocalName(i));
- locals->set(i * 2 + 1, frame_inspector.GetExpression(i));
+ if (scope_info->LocalIsSynthetic(i))
+ continue;
+ locals->set(local * 2, scope_info->LocalName(i));
+ locals->set(local * 2 + 1, frame_inspector.GetExpression(i));
+ local++;
}
- if (i < scope_info->LocalCount()) {
+ if (local < local_count) {
// Get the context containing declarations.
Handle<Context> context(
Context::cast(it.frame()->context())->declaration_context());
for (; i < scope_info->LocalCount(); ++i) {
+ if (scope_info->LocalIsSynthetic(i))
+ continue;
Handle<String> name(scope_info->LocalName(i));
VariableMode mode;
InitializationFlag init_flag;
- locals->set(i * 2, *name);
+ locals->set(local * 2, *name);
int context_slot_index =
- scope_info->ContextSlotIndex(*name, &mode, &init_flag);
+ ScopeInfo::ContextSlotIndex(scope_info, name, &mode, &init_flag);
Object* value = context->get(context_slot_index);
- locals->set(i * 2 + 1, value);
+ locals->set(local * 2 + 1, value);
+ local++;
}
}
@@ -11371,7 +11357,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
// Calculate the size of the result.
int details_size = kFrameDetailsFirstDynamicIndex +
- 2 * (argument_count + scope_info->LocalCount()) +
+ 2 * (argument_count + local_count) +
(at_return ? 1 : 0);
Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
@@ -11386,7 +11372,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
// Add the locals count
details->set(kFrameDetailsLocalCountIndex,
- Smi::FromInt(scope_info->LocalCount()));
+ Smi::FromInt(local_count));
// Add the source position.
if (position != RelocInfo::kNoPosition) {
@@ -11437,7 +11423,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
}
// Add locals name and value from the temporary copy from the function frame.
- for (int i = 0; i < scope_info->LocalCount() * 2; i++) {
+ for (int i = 0; i < local_count * 2; i++) {
details->set(details_index++, locals->get(i));
}
@@ -11467,7 +11453,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
ASSERT(!receiver->IsNull());
Context* context = Context::cast(it.frame()->context());
Handle<Context> native_context(Context::cast(context->native_context()));
- receiver = isolate->factory()->ToObject(receiver, native_context);
+ receiver = Object::ToObject(
+ isolate, receiver, native_context).ToHandleChecked();
}
}
details->set(kFrameDetailsReceiverIndex, *receiver);
@@ -11478,16 +11465,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
static bool ParameterIsShadowedByContextLocal(Handle<ScopeInfo> info,
- int index) {
+ Handle<String> parameter_name) {
VariableMode mode;
InitializationFlag flag;
- return info->ContextSlotIndex(info->ParameterName(index), &mode, &flag) != -1;
+ return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &flag) != -1;
}
// Create a plain JSObject which materializes the local scope for the specified
// frame.
-static Handle<JSObject> MaterializeStackLocalsWithFrameInspector(
+MUST_USE_RESULT
+static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
Isolate* isolate,
Handle<JSObject> target,
Handle<JSFunction> function,
@@ -11498,7 +11486,8 @@ static Handle<JSObject> MaterializeStackLocalsWithFrameInspector(
// First fill all parameters.
for (int i = 0; i < scope_info->ParameterCount(); ++i) {
// Do not materialize the parameter if it is shadowed by a context local.
- if (ParameterIsShadowedByContextLocal(scope_info, i)) continue;
+ Handle<String> name(scope_info->ParameterName(i));
+ if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
HandleScope scope(isolate);
Handle<Object> value(i < frame_inspector->GetParametersCount()
@@ -11506,24 +11495,24 @@ static Handle<JSObject> MaterializeStackLocalsWithFrameInspector(
: isolate->heap()->undefined_value(),
isolate);
ASSERT(!value->IsTheHole());
- Handle<String> name(scope_info->ParameterName(i));
- RETURN_IF_EMPTY_HANDLE_VALUE(
+ RETURN_ON_EXCEPTION(
isolate,
Runtime::SetObjectProperty(isolate, target, name, value, NONE, SLOPPY),
- Handle<JSObject>());
+ JSObject);
}
// Second fill all stack locals.
for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
+ if (scope_info->LocalIsSynthetic(i)) continue;
Handle<String> name(scope_info->StackLocalName(i));
Handle<Object> value(frame_inspector->GetExpression(i), isolate);
if (value->IsTheHole()) continue;
- RETURN_IF_EMPTY_HANDLE_VALUE(
+ RETURN_ON_EXCEPTION(
isolate,
Runtime::SetObjectProperty(isolate, target, name, value, NONE, SLOPPY),
- Handle<JSObject>());
+ JSObject);
}
return target;
@@ -11548,30 +11537,34 @@ static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
// Parameters.
for (int i = 0; i < scope_info->ParameterCount(); ++i) {
// Shadowed parameters were not materialized.
- if (ParameterIsShadowedByContextLocal(scope_info, i)) continue;
+ Handle<String> name(scope_info->ParameterName(i));
+ if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
ASSERT(!frame->GetParameter(i)->IsTheHole());
HandleScope scope(isolate);
- Handle<String> name(scope_info->ParameterName(i));
- Handle<Object> value = GetProperty(isolate, target, name);
+ Handle<Object> value =
+ Object::GetPropertyOrElement(target, name).ToHandleChecked();
frame->SetParameterValue(i, *value);
}
// Stack locals.
for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
+ if (scope_info->LocalIsSynthetic(i)) continue;
if (frame->GetExpression(i)->IsTheHole()) continue;
HandleScope scope(isolate);
- Handle<Object> value = GetProperty(
- isolate, target, Handle<String>(scope_info->StackLocalName(i)));
+ Handle<Object> value = Object::GetPropertyOrElement(
+ target,
+ handle(scope_info->StackLocalName(i), isolate)).ToHandleChecked();
frame->SetExpression(i, *value);
}
}
-static Handle<JSObject> MaterializeLocalContext(Isolate* isolate,
- Handle<JSObject> target,
- Handle<JSFunction> function,
- JavaScriptFrame* frame) {
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext(
+ Isolate* isolate,
+ Handle<JSObject> target,
+ Handle<JSFunction> function,
+ JavaScriptFrame* frame) {
HandleScope scope(isolate);
Handle<SharedFunctionInfo> shared(function->shared());
Handle<ScopeInfo> scope_info(shared->scope_info());
@@ -11583,7 +11576,7 @@ static Handle<JSObject> MaterializeLocalContext(Isolate* isolate,
Handle<Context> function_context(frame_context->declaration_context());
if (!ScopeInfo::CopyContextLocalsToScopeObject(
scope_info, function_context, target)) {
- return Handle<JSObject>();
+ return MaybeHandle<JSObject>();
}
// Finally copy any properties from the function context extension.
@@ -11592,24 +11585,24 @@ static Handle<JSObject> MaterializeLocalContext(Isolate* isolate,
if (function_context->has_extension() &&
!function_context->IsNativeContext()) {
Handle<JSObject> ext(JSObject::cast(function_context->extension()));
- bool threw = false;
- Handle<FixedArray> keys =
- GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw);
- if (threw) return Handle<JSObject>();
+ Handle<FixedArray> keys;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, keys,
+ JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
+ JSObject);
for (int i = 0; i < keys->length(); i++) {
// Names of variables introduced by eval are strings.
ASSERT(keys->get(i)->IsString());
Handle<String> key(String::cast(keys->get(i)));
- RETURN_IF_EMPTY_HANDLE_VALUE(
+ Handle<Object> value;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
+ RETURN_ON_EXCEPTION(
isolate,
- Runtime::SetObjectProperty(isolate,
- target,
- key,
- GetProperty(isolate, ext, key),
- NONE,
- SLOPPY),
- Handle<JSObject>());
+ Runtime::SetObjectProperty(
+ isolate, target, key, value, NONE, SLOPPY),
+ JSObject);
}
}
}
@@ -11618,7 +11611,7 @@ static Handle<JSObject> MaterializeLocalContext(Isolate* isolate,
}
-static Handle<JSObject> MaterializeLocalScope(
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope(
Isolate* isolate,
JavaScriptFrame* frame,
int inlined_jsframe_index) {
@@ -11627,9 +11620,11 @@ static Handle<JSObject> MaterializeLocalScope(
Handle<JSObject> local_scope =
isolate->factory()->NewJSObject(isolate->object_function());
- local_scope = MaterializeStackLocalsWithFrameInspector(
- isolate, local_scope, function, &frame_inspector);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, local_scope, Handle<JSObject>());
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, local_scope,
+ MaterializeStackLocalsWithFrameInspector(
+ isolate, local_scope, function, &frame_inspector),
+ JSObject);
return MaterializeLocalContext(isolate, local_scope, function, frame);
}
@@ -11643,11 +11638,11 @@ static bool SetContextLocalValue(Isolate* isolate,
Handle<Object> new_value) {
for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
Handle<String> next_name(scope_info->ContextLocalName(i));
- if (variable_name->Equals(*next_name)) {
+ if (String::Equals(variable_name, next_name)) {
VariableMode mode;
InitializationFlag init_flag;
int context_index =
- scope_info->ContextSlotIndex(*next_name, &mode, &init_flag);
+ ScopeInfo::ContextSlotIndex(scope_info, next_name, &mode, &init_flag);
context->set(context_index, *new_value);
return true;
}
@@ -11675,7 +11670,8 @@ static bool SetLocalVariableValue(Isolate* isolate,
// Parameters.
for (int i = 0; i < scope_info->ParameterCount(); ++i) {
- if (scope_info->ParameterName(i)->Equals(*variable_name)) {
+ HandleScope scope(isolate);
+ if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) {
frame->SetParameterValue(i, *new_value);
// Argument might be shadowed in heap context, don't stop here.
default_result = true;
@@ -11684,7 +11680,8 @@ static bool SetLocalVariableValue(Isolate* isolate,
// Stack locals.
for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
- if (scope_info->StackLocalName(i)->Equals(*variable_name)) {
+ HandleScope scope(isolate);
+ if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
frame->SetExpression(i, *new_value);
return true;
}
@@ -11709,7 +11706,7 @@ static bool SetLocalVariableValue(Isolate* isolate,
// We don't expect this to do anything except replacing
// property value.
Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
- NONE, SLOPPY);
+ NONE, SLOPPY).Assert();
return true;
}
}
@@ -11722,8 +11719,9 @@ static bool SetLocalVariableValue(Isolate* isolate,
// Create a plain JSObject which materializes the closure content for the
// context.
-static Handle<JSObject> MaterializeClosure(Isolate* isolate,
- Handle<Context> context) {
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure(
+ Isolate* isolate,
+ Handle<Context> context) {
ASSERT(context->IsFunctionContext());
Handle<SharedFunctionInfo> shared(context->closure()->shared());
@@ -11737,28 +11735,31 @@ static Handle<JSObject> MaterializeClosure(Isolate* isolate,
// Fill all context locals to the context extension.
if (!ScopeInfo::CopyContextLocalsToScopeObject(
scope_info, context, closure_scope)) {
- return Handle<JSObject>();
+ return MaybeHandle<JSObject>();
}
// Finally copy any properties from the function context extension. This will
// be variables introduced by eval.
if (context->has_extension()) {
Handle<JSObject> ext(JSObject::cast(context->extension()));
- bool threw = false;
- Handle<FixedArray> keys =
- GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw);
- if (threw) return Handle<JSObject>();
+ Handle<FixedArray> keys;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, keys,
+ JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS), JSObject);
for (int i = 0; i < keys->length(); i++) {
+ HandleScope scope(isolate);
// Names of variables introduced by eval are strings.
ASSERT(keys->get(i)->IsString());
Handle<String> key(String::cast(keys->get(i)));
- RETURN_IF_EMPTY_HANDLE_VALUE(
+ Handle<Object> value;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
+ RETURN_ON_EXCEPTION(
isolate,
- Runtime::SetObjectProperty(isolate, closure_scope, key,
- GetProperty(isolate, ext, key),
- NONE, SLOPPY),
- Handle<JSObject>());
+ Runtime::SetObjectProperty(
+ isolate, closure_scope, key, value, NONE, SLOPPY),
+ JSObject);
}
}
@@ -11789,7 +11790,7 @@ static bool SetClosureVariableValue(Isolate* isolate,
if (JSReceiver::HasProperty(ext, variable_name)) {
// We don't expect this to do anything except replacing property value.
Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
- NONE, SLOPPY);
+ NONE, SLOPPY).Assert();
return true;
}
}
@@ -11800,19 +11801,20 @@ static bool SetClosureVariableValue(Isolate* isolate,
// Create a plain JSObject which materializes the scope for the specified
// catch context.
-static Handle<JSObject> MaterializeCatchScope(Isolate* isolate,
- Handle<Context> context) {
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
+ Isolate* isolate,
+ Handle<Context> context) {
ASSERT(context->IsCatchContext());
Handle<String> name(String::cast(context->extension()));
Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
isolate);
Handle<JSObject> catch_scope =
isolate->factory()->NewJSObject(isolate->object_function());
- RETURN_IF_EMPTY_HANDLE_VALUE(
+ RETURN_ON_EXCEPTION(
isolate,
Runtime::SetObjectProperty(isolate, catch_scope, name, thrown_object,
NONE, SLOPPY),
- Handle<JSObject>());
+ JSObject);
return catch_scope;
}
@@ -11823,7 +11825,7 @@ static bool SetCatchVariableValue(Isolate* isolate,
Handle<Object> new_value) {
ASSERT(context->IsCatchContext());
Handle<String> name(String::cast(context->extension()));
- if (!name->Equals(*variable_name)) {
+ if (!String::Equals(name, variable_name)) {
return false;
}
context->set(Context::THROWN_OBJECT_INDEX, *new_value);
@@ -11833,7 +11835,7 @@ static bool SetCatchVariableValue(Isolate* isolate,
// Create a plain JSObject which materializes the block scope for the specified
// block context.
-static Handle<JSObject> MaterializeBlockScope(
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope(
Isolate* isolate,
Handle<Context> context) {
ASSERT(context->IsBlockContext());
@@ -11847,7 +11849,7 @@ static Handle<JSObject> MaterializeBlockScope(
// Fill all context locals.
if (!ScopeInfo::CopyContextLocalsToScopeObject(
scope_info, context, block_scope)) {
- return Handle<JSObject>();
+ return MaybeHandle<JSObject>();
}
return block_scope;
@@ -11856,7 +11858,7 @@ static Handle<JSObject> MaterializeBlockScope(
// Create a plain JSObject which materializes the module scope for the specified
// module context.
-static Handle<JSObject> MaterializeModuleScope(
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
Isolate* isolate,
Handle<Context> context) {
ASSERT(context->IsModuleContext());
@@ -11870,7 +11872,7 @@ static Handle<JSObject> MaterializeModuleScope(
// Fill all context locals.
if (!ScopeInfo::CopyContextLocalsToScopeObject(
scope_info, context, module_scope)) {
- return Handle<JSObject>();
+ return MaybeHandle<JSObject>();
}
return module_scope;
@@ -12080,7 +12082,7 @@ class ScopeIterator {
}
// Return the JavaScript object with the content of the current scope.
- Handle<JSObject> ScopeObject() {
+ MaybeHandle<JSObject> ScopeObject() {
ASSERT(!failed_);
switch (Type()) {
case ScopeIterator::ScopeTypeGlobal:
@@ -12243,16 +12245,12 @@ class ScopeIterator {
};
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) {
+RUNTIME_FUNCTION(Runtime_GetScopeCount) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
// Get the frame where the debugging is performed.
@@ -12275,16 +12273,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) {
// Returns the list of step-in positions (text offset) in a function of the
// stack frame in a range from the current debug break position to the end
// of the corresponding statement.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetStepInPositions) {
+RUNTIME_FUNCTION(Runtime_GetStepInPositions) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
// Get the frame where the debugging is performed.
@@ -12335,9 +12329,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetStepInPositions) {
if (accept) {
if (break_location_iterator.IsStepInLocation(isolate)) {
Smi* position_value = Smi::FromInt(break_location_iterator.position());
- JSObject::SetElement(array, len,
- Handle<Object>(position_value, isolate),
- NONE, SLOPPY);
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate,
+ JSObject::SetElement(array, len,
+ Handle<Object>(position_value, isolate),
+ NONE, SLOPPY));
len++;
}
}
@@ -12357,7 +12353,8 @@ static const int kScopeDetailsObjectIndex = 1;
static const int kScopeDetailsSize = 2;
-static Handle<JSObject> MaterializeScopeDetails(Isolate* isolate,
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScopeDetails(
+ Isolate* isolate,
ScopeIterator* it) {
// Calculate the size of the result.
int details_size = kScopeDetailsSize;
@@ -12365,8 +12362,9 @@ static Handle<JSObject> MaterializeScopeDetails(Isolate* isolate,
// Fill in scope details.
details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type()));
- Handle<JSObject> scope_object = it->ScopeObject();
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, scope_object, Handle<JSObject>());
+ Handle<JSObject> scope_object;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, scope_object, it->ScopeObject(), JSObject);
details->set(kScopeDetailsObjectIndex, *scope_object);
return isolate->factory()->NewJSArrayWithElements(details);
@@ -12382,16 +12380,12 @@ static Handle<JSObject> MaterializeScopeDetails(Isolate* isolate,
// The array returned contains the following information:
// 0: Scope type
// 1: Scope object
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
+RUNTIME_FUNCTION(Runtime_GetScopeDetails) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
@@ -12410,8 +12404,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
if (it.Done()) {
return isolate->heap()->undefined_value();
}
- Handle<JSObject> details = MaterializeScopeDetails(isolate, &it);
- RETURN_IF_EMPTY_HANDLE(isolate, details);
+ Handle<JSObject> details;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, details, MaterializeScopeDetails(isolate, &it));
return *details;
}
@@ -12425,16 +12420,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
// The array returned contains arrays with the following information:
// 0: Scope type
// 1: Scope object
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAllScopesDetails) {
+RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
HandleScope scope(isolate);
ASSERT(args.length() == 3 || args.length() == 4);
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
@@ -12452,8 +12443,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAllScopesDetails) {
List<Handle<JSObject> > result(4);
ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes);
for (; !it.Done(); it.Next()) {
- Handle<JSObject> details = MaterializeScopeDetails(isolate, &it);
- RETURN_IF_EMPTY_HANDLE(isolate, details);
+ Handle<JSObject> details;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, details, MaterializeScopeDetails(isolate, &it));
result.Add(details);
}
@@ -12465,7 +12457,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAllScopesDetails) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeCount) {
+RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
@@ -12482,7 +12474,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeCount) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeDetails) {
+RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -12500,8 +12492,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionScopeDetails) {
return isolate->heap()->undefined_value();
}
- Handle<JSObject> details = MaterializeScopeDetails(isolate, &it);
- RETURN_IF_EMPTY_HANDLE(isolate, details);
+ Handle<JSObject> details;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, details, MaterializeScopeDetails(isolate, &it));
return *details;
}
@@ -12528,22 +12521,20 @@ static bool SetScopeVariableValue(ScopeIterator* it, int index,
// args[5]: object: new value
//
// Return true if success and false otherwise
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScopeVariableValue) {
+RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
HandleScope scope(isolate);
ASSERT(args.length() == 6);
// Check arguments.
CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
- Handle<Object> new_value = args.at<Object>(5);
+ CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
bool res;
if (args[0]->IsNumber()) {
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
+
CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
@@ -12564,7 +12555,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScopeVariableValue) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) {
+RUNTIME_FUNCTION(Runtime_DebugPrintScopes) {
HandleScope scope(isolate);
ASSERT(args.length() == 0);
@@ -12582,16 +12573,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetThreadCount) {
+RUNTIME_FUNCTION(Runtime_GetThreadCount) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
-
- // Check arguments.
- Object* result;
- { MaybeObject* maybe_result = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
// Count all archived V8 threads.
int n = 0;
@@ -12618,16 +12604,12 @@ static const int kThreadDetailsSize = 2;
// The array returned contains the following information:
// 0: Is current thread?
// 1: Thread id
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetThreadDetails) {
+RUNTIME_FUNCTION(Runtime_GetThreadDetails) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
// Allocate array for result.
@@ -12668,7 +12650,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetThreadDetails) {
// Sets the disable break state
// args[0]: disable break state
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDisableBreak) {
+RUNTIME_FUNCTION(Runtime_SetDisableBreak) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
@@ -12682,7 +12664,7 @@ static bool IsPositionAlignmentCodeCorrect(int alignment) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetBreakLocations) {
+RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -12710,13 +12692,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetBreakLocations) {
// args[0]: function
// args[1]: number: break source position (within the function source)
// args[2]: number: break point object
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFunctionBreakPoint) {
+RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
RUNTIME_ASSERT(source_position >= 0);
- Handle<Object> break_point_object_arg = args.at<Object>(2);
+ CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
// Set break point.
isolate->debug()->SetBreakPoint(function, break_point_object_arg,
@@ -12733,14 +12715,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFunctionBreakPoint) {
// args[1]: number: break source position (within the script source)
// args[2]: number, breakpoint position alignment
// args[3]: number: break point object
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScriptBreakPoint) {
+RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
RUNTIME_ASSERT(source_position >= 0);
CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
- Handle<Object> break_point_object_arg = args.at<Object>(3);
+ CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3);
if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
return isolate->ThrowIllegalOperation();
@@ -12765,10 +12747,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScriptBreakPoint) {
// Clear a break point
// args[0]: number: break point object
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearBreakPoint) {
+RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- Handle<Object> break_point_object_arg = args.at<Object>(0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
// Clear break point.
isolate->debug()->ClearBreakPoint(break_point_object_arg);
@@ -12780,16 +12762,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearBreakPoint) {
// Change the state of break on exceptions.
// args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
// args[1]: Boolean indicating on/off.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ChangeBreakOnException) {
+RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- RUNTIME_ASSERT(args[0]->IsNumber());
+ CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
// If the number doesn't match an enum value, the ChangeBreakOnException
// function will default to affecting caught exceptions.
- ExceptionBreakType type =
- static_cast<ExceptionBreakType>(NumberToUint32(args[0]));
+ ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
// Update break point state.
isolate->debug()->ChangeBreakOnException(type, enable);
return isolate->heap()->undefined_value();
@@ -12798,13 +12779,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ChangeBreakOnException) {
// Returns the state of break on exceptions
// args[0]: boolean indicating uncaught exceptions
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsBreakOnException) {
+RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- RUNTIME_ASSERT(args[0]->IsNumber());
+ CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
- ExceptionBreakType type =
- static_cast<ExceptionBreakType>(NumberToUint32(args[0]));
+ ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
bool result = isolate->debug()->IsBreakOnException(type);
return Smi::FromInt(result);
}
@@ -12815,15 +12795,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsBreakOnException) {
// args[1]: step action from the enumeration StepAction
// args[2]: number of times to perform the step, for step out it is the number
// of frames to step down.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_PrepareStep) {
+RUNTIME_FUNCTION(Runtime_PrepareStep) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
+
if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
return isolate->Throw(isolate->heap()->illegal_argument_string());
}
@@ -12870,7 +12847,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PrepareStep) {
// Clear all stepping set by PrepareStep.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) {
+RUNTIME_FUNCTION(Runtime_ClearStepping) {
HandleScope scope(isolate);
ASSERT(args.length() == 0);
isolate->debug()->ClearStepping();
@@ -12880,7 +12857,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) {
// Helper function to find or create the arguments object for
// Runtime_DebugEvaluate.
-static Handle<JSObject> MaterializeArgumentsObject(
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
Isolate* isolate,
Handle<JSObject> target,
Handle<JSFunction> function) {
@@ -12895,40 +12872,43 @@ static Handle<JSObject> MaterializeArgumentsObject(
// FunctionGetArguments can't throw an exception.
Handle<JSObject> arguments = Handle<JSObject>::cast(
Accessors::FunctionGetArguments(function));
- Runtime::SetObjectProperty(isolate, target,
- isolate->factory()->arguments_string(),
- arguments,
- ::NONE,
- SLOPPY);
+ Handle<String> arguments_str = isolate->factory()->arguments_string();
+ RETURN_ON_EXCEPTION(
+ isolate,
+ Runtime::SetObjectProperty(
+ isolate, target, arguments_str, arguments, ::NONE, SLOPPY),
+ JSObject);
return target;
}
// Compile and evaluate source for the given context.
-static MaybeObject* DebugEvaluate(Isolate* isolate,
- Handle<Context> context,
- Handle<Object> context_extension,
- Handle<Object> receiver,
- Handle<String> source) {
+static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
+ Handle<Context> context,
+ Handle<Object> context_extension,
+ Handle<Object> receiver,
+ Handle<String> source) {
if (context_extension->IsJSObject()) {
Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
Handle<JSFunction> closure(context->closure(), isolate);
context = isolate->factory()->NewWithContext(closure, context, extension);
}
- Handle<JSFunction> eval_fun =
+ Handle<JSFunction> eval_fun;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, eval_fun,
Compiler::GetFunctionFromEval(source,
context,
SLOPPY,
NO_PARSE_RESTRICTION,
- RelocInfo::kNoPosition);
- RETURN_IF_EMPTY_HANDLE(isolate, eval_fun);
+ RelocInfo::kNoPosition),
+ Object);
- bool pending_exception;
- Handle<Object> result = Execution::Call(
- isolate, eval_fun, receiver, 0, NULL, &pending_exception);
-
- if (pending_exception) return Failure::Exception();
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ Execution::Call(isolate, eval_fun, receiver, 0, NULL),
+ Object);
// Skip the global proxy as it has no properties and always delegates to the
// real global object.
@@ -12938,7 +12918,7 @@ static MaybeObject* DebugEvaluate(Isolate* isolate,
// Clear the oneshot breakpoints so that the debugger does not step further.
isolate->debug()->ClearStepping();
- return *result;
+ return result;
}
@@ -12947,22 +12927,20 @@ static MaybeObject* DebugEvaluate(Isolate* isolate,
// - Parameters and stack-allocated locals need to be materialized. Altered
// values need to be written back to the stack afterwards.
// - The arguments object needs to materialized.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
+RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
HandleScope scope(isolate);
// Check the execution state and decode arguments frame and source to be
// evaluated.
ASSERT(args.length() == 6);
- Object* check_result;
- { MaybeObject* maybe_result = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_result->ToObject(&check_result)) return maybe_result;
- }
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
+
CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
- Handle<Object> context_extension(args[5], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5);
// Handle the processing of break.
DisableBreak disable_break_save(isolate, disable_break);
@@ -12989,24 +12967,23 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
Handle<JSObject> materialized =
isolate->factory()->NewJSObject(isolate->object_function());
- materialized = MaterializeStackLocalsWithFrameInspector(
- isolate, materialized, function, &frame_inspector);
- RETURN_IF_EMPTY_HANDLE(isolate, materialized);
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, materialized,
+ MaterializeStackLocalsWithFrameInspector(
+ isolate, materialized, function, &frame_inspector));
- materialized = MaterializeArgumentsObject(isolate, materialized, function);
- RETURN_IF_EMPTY_HANDLE(isolate, materialized);
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, materialized,
+ MaterializeArgumentsObject(isolate, materialized, function));
// Add the materialized object in a with-scope to shadow the stack locals.
context = isolate->factory()->NewWithContext(function, context, materialized);
Handle<Object> receiver(frame->receiver(), isolate);
- Object* evaluate_result_object;
- { MaybeObject* maybe_result =
- DebugEvaluate(isolate, context, context_extension, receiver, source);
- if (!maybe_result->ToObject(&evaluate_result_object)) return maybe_result;
- }
-
- Handle<Object> result(evaluate_result_object, isolate);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ DebugEvaluate(isolate, context, context_extension, receiver, source));
// Write back potential changes to materialized stack locals to the stack.
UpdateStackLocalsFromMaterializedObject(
@@ -13016,20 +12993,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
+RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
HandleScope scope(isolate);
// Check the execution state and decode arguments frame and source to be
// evaluated.
ASSERT(args.length() == 4);
- Object* check_result;
- { MaybeObject* maybe_result = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_result->ToObject(&check_result)) return maybe_result;
- }
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
+
CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
- Handle<Object> context_extension(args[3], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 3);
// Handle the processing of break.
DisableBreak disable_break_save(isolate, disable_break);
@@ -13048,11 +13023,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
// debugger was invoked.
Handle<Context> context = isolate->native_context();
Handle<Object> receiver = isolate->global_object();
- return DebugEvaluate(isolate, context, context_extension, receiver, source);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ DebugEvaluate(isolate, context, context_extension, receiver, source));
+ return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetLoadedScripts) {
+RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
HandleScope scope(isolate);
ASSERT(args.length() == 0);
@@ -13067,7 +13046,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetLoadedScripts) {
// instances->set(i, *GetScriptWrapper(script))
// is unsafe as GetScriptWrapper might call GC and the C++ compiler might
// already have dereferenced the instances handle.
- Handle<JSValue> wrapper = GetScriptWrapper(script);
+ Handle<JSObject> wrapper = Script::GetWrapper(script);
instances->set(i, *wrapper);
}
@@ -13154,7 +13133,7 @@ static int DebugReferencedBy(HeapIterator* iterator,
// args[0]: the object to find references to
// args[1]: constructor function for instances to exclude (Mirror)
// args[2]: the the maximum number of objects to return
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
+RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
@@ -13168,7 +13147,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) {
// Check parameters.
CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
- Handle<Object> instance_filter = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1);
RUNTIME_ASSERT(instance_filter->IsUndefined() ||
instance_filter->IsJSObject());
CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
@@ -13244,7 +13223,7 @@ static int DebugConstructedBy(HeapIterator* iterator,
// Scan the heap for objects constructed by a specific function.
// args[0]: the constructor to find instances of
// args[1]: the the maximum number of objects to return
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
+RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -13289,16 +13268,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) {
// Find the effective prototype object as returned by __proto__.
// args[0]: the object to find the prototype for.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
+ HandleScope shs(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
- return GetPrototypeSkipHiddenPrototypes(isolate, obj);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+ return *GetPrototypeSkipHiddenPrototypes(isolate, obj);
}
// Patches script source (should be called upon BeforeCompile event).
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugSetScriptSource) {
+RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -13316,7 +13295,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugSetScriptSource) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SystemBreak) {
+RUNTIME_FUNCTION(Runtime_SystemBreak) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 0);
OS::DebugBreak();
@@ -13324,14 +13303,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SystemBreak) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleFunction) {
+RUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) {
HandleScope scope(isolate);
#ifdef DEBUG
ASSERT(args.length() == 1);
// Get the function and make sure it is compiled.
CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
- return Failure::Exception();
+ return isolate->heap()->exception();
}
func->code()->PrintLn();
#endif // DEBUG
@@ -13339,14 +13318,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleFunction) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleConstructor) {
+RUNTIME_FUNCTION(Runtime_DebugDisassembleConstructor) {
HandleScope scope(isolate);
#ifdef DEBUG
ASSERT(args.length() == 1);
// Get the function and make sure it is compiled.
CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
- return Failure::Exception();
+ return isolate->heap()->exception();
}
func->shared()->construct_stub()->PrintLn();
#endif // DEBUG
@@ -13354,7 +13333,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleConstructor) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetInferredName) {
+RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
@@ -13392,8 +13371,7 @@ static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
// For a script finds all SharedFunctionInfo's in the heap that points
// to this script. Returns JSArray of SharedFunctionInfo wrapped
// in OpaqueReferences.
-RUNTIME_FUNCTION(MaybeObject*,
- Runtime_LiveEditFindSharedFunctionInfosForScript) {
+RUNTIME_FUNCTION(Runtime_LiveEditFindSharedFunctionInfosForScript) {
HandleScope scope(isolate);
CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 1);
@@ -13442,7 +13420,7 @@ RUNTIME_FUNCTION(MaybeObject*,
// Returns a JSArray of compilation infos. The array is ordered so that
// each function with all its descendant is always stored in a continues range
// with the function itself going first. The root function is a script function.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditGatherCompileInfo) {
+RUNTIME_FUNCTION(Runtime_LiveEditGatherCompileInfo) {
HandleScope scope(isolate);
CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
@@ -13452,71 +13430,72 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditGatherCompileInfo) {
RUNTIME_ASSERT(script->value()->IsScript());
Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
- JSArray* result = LiveEdit::GatherCompileInfo(script_handle, source);
-
- if (isolate->has_pending_exception()) {
- return Failure::Exception();
- }
-
- return result;
+ Handle<JSArray> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, LiveEdit::GatherCompileInfo(script_handle, source));
+ return *result;
}
// Changes the source of the script to a new_source.
// If old_script_name is provided (i.e. is a String), also creates a copy of
// the script with its original source and sends notification to debugger.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceScript) {
+RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) {
HandleScope scope(isolate);
CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 3);
CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
- Handle<Object> old_script_name(args[2], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2);
RUNTIME_ASSERT(original_script_value->value()->IsScript());
Handle<Script> original_script(Script::cast(original_script_value->value()));
- Object* old_script = LiveEdit::ChangeScriptSource(original_script,
- new_source,
- old_script_name);
+ Handle<Object> old_script = LiveEdit::ChangeScriptSource(
+ original_script, new_source, old_script_name);
if (old_script->IsScript()) {
- Handle<Script> script_handle(Script::cast(old_script));
- return *(GetScriptWrapper(script_handle));
+ Handle<Script> script_handle = Handle<Script>::cast(old_script);
+ return *Script::GetWrapper(script_handle);
} else {
return isolate->heap()->null_value();
}
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSourceUpdated) {
+RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) {
HandleScope scope(isolate);
CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
- return LiveEdit::FunctionSourceUpdated(shared_info);
+ RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
+
+ LiveEdit::FunctionSourceUpdated(shared_info);
+ return isolate->heap()->undefined_value();
}
// Replaces code of SharedFunctionInfo with a new one.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceFunctionCode) {
+RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) {
HandleScope scope(isolate);
CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
+ RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
- return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
+ LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
+ return isolate->heap()->undefined_value();
}
// Connects SharedFunctionInfo to another script.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSetScript) {
+RUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) {
HandleScope scope(isolate);
CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
- Handle<Object> function_object(args[0], isolate);
- Handle<Object> script_object(args[1], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1);
if (function_object->IsJSValue()) {
Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
@@ -13538,7 +13517,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditFunctionSetScript) {
// In a code of a parent function replaces original function as embedded object
// with a substitution one.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceRefToNestedFunction) {
+RUNTIME_FUNCTION(Runtime_LiveEditReplaceRefToNestedFunction) {
HandleScope scope(isolate);
CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 3);
@@ -13546,10 +13525,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceRefToNestedFunction) {
CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
+ RUNTIME_ASSERT(parent_wrapper->value()->IsSharedFunctionInfo());
+ RUNTIME_ASSERT(orig_wrapper->value()->IsSharedFunctionInfo());
+ RUNTIME_ASSERT(subst_wrapper->value()->IsSharedFunctionInfo());
- LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper,
- subst_wrapper);
-
+ LiveEdit::ReplaceRefToNestedFunction(
+ parent_wrapper, orig_wrapper, subst_wrapper);
return isolate->heap()->undefined_value();
}
@@ -13559,14 +13540,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditReplaceRefToNestedFunction) {
// array of groups of 3 numbers:
// (change_begin, change_end, change_end_new_position).
// Each group describes a change in text; groups are sorted by change_begin.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditPatchFunctionPositions) {
+RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) {
HandleScope scope(isolate);
CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
+ RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_array))
- return LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
+ LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
+ return isolate->heap()->undefined_value();
}
@@ -13574,12 +13557,21 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditPatchFunctionPositions) {
// checks that none of them have activations on stacks (of any thread).
// Returns array of the same length with corresponding results of
// LiveEdit::FunctionPatchabilityStatus type.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCheckAndDropActivations) {
+RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) {
HandleScope scope(isolate);
CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
+ RUNTIME_ASSERT(shared_array->length()->IsSmi());
+ int array_length = Smi::cast(shared_array->length())->value();
+ for (int i = 0; i < array_length; i++) {
+ Handle<Object> element =
+ Object::GetElement(isolate, shared_array, i).ToHandleChecked();
+ RUNTIME_ASSERT(
+ element->IsJSValue() &&
+ Handle<JSValue>::cast(element)->value()->IsSharedFunctionInfo());
+ }
return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
}
@@ -13588,7 +13580,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCheckAndDropActivations) {
// Compares 2 strings line-by-line, then token-wise and returns diff in form
// of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
// of diff chunks.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCompareStrings) {
+RUNTIME_FUNCTION(Runtime_LiveEditCompareStrings) {
HandleScope scope(isolate);
CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
@@ -13601,17 +13593,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCompareStrings) {
// Restarts a call frame and completely drops all frames above.
// Returns true if successful. Otherwise returns undefined or an error message.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditRestartFrame) {
+RUNTIME_FUNCTION(Runtime_LiveEditRestartFrame) {
HandleScope scope(isolate);
CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
Heap* heap = isolate->heap();
@@ -13640,7 +13628,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditRestartFrame) {
// A testing entry. Returns statement position which is the closest to
// source_position.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionCodePositionFromSource) {
+RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
HandleScope scope(isolate);
CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
@@ -13678,43 +13666,37 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionCodePositionFromSource) {
// Calls specified function with or without entering the debugger.
// This is used in unit tests to run code as if debugger is entered or simply
// to have a stack with C++ frame in the middle.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ExecuteInDebugContext) {
+RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
- Handle<Object> result;
- bool pending_exception;
- {
- if (without_debugger) {
- result = Execution::Call(isolate,
- function,
- isolate->global_object(),
- 0,
- NULL,
- &pending_exception);
- } else {
- EnterDebugger enter_debugger(isolate);
- result = Execution::Call(isolate,
- function,
- isolate->global_object(),
- 0,
- NULL,
- &pending_exception);
- }
- }
- if (!pending_exception) {
- return *result;
+ MaybeHandle<Object> maybe_result;
+ if (without_debugger) {
+ maybe_result = Execution::Call(isolate,
+ function,
+ isolate->global_object(),
+ 0,
+ NULL);
} else {
- return Failure::Exception();
+ EnterDebugger enter_debugger(isolate);
+ maybe_result = Execution::Call(isolate,
+ function,
+ isolate->global_object(),
+ 0,
+ NULL);
}
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
+ return *result;
}
// Sets a v8 flag.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFlags) {
+RUNTIME_FUNCTION(Runtime_SetFlags) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(String, arg, 0);
SmartArrayPointer<char> flags =
arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
@@ -13725,16 +13707,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFlags) {
// Performs a GC.
// Presently, it only does a full GC.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectGarbage) {
+RUNTIME_FUNCTION(Runtime_CollectGarbage) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 1);
isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
return isolate->heap()->undefined_value();
}
// Gets the current heap usage.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHeapUsage) {
+RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 0);
int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
if (!Smi::IsValid(usage)) {
return *isolate->factory()->NewNumberFromInt(usage);
@@ -13742,12 +13726,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHeapUsage) {
return Smi::FromInt(usage);
}
-#endif // ENABLE_DEBUGGER_SUPPORT
-
#ifdef V8_I18N_SUPPORT
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CanonicalizeLanguageTag) {
+RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) {
HandleScope scope(isolate);
+ Factory* factory = isolate->factory();
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0);
@@ -13764,7 +13747,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CanonicalizeLanguageTag) {
uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
&icu_length, &error);
if (U_FAILURE(error) || icu_length == 0) {
- return isolate->heap()->AllocateStringFromOneByte(CStrVector(kInvalidTag));
+ return *factory->NewStringFromAsciiChecked(kInvalidTag);
}
char result[ULOC_FULLNAME_CAPACITY];
@@ -13773,15 +13756,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CanonicalizeLanguageTag) {
uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
if (U_FAILURE(error)) {
- return isolate->heap()->AllocateStringFromOneByte(CStrVector(kInvalidTag));
+ return *factory->NewStringFromAsciiChecked(kInvalidTag);
}
- return isolate->heap()->AllocateStringFromOneByte(CStrVector(result));
+ return *factory->NewStringFromAsciiChecked(result);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_AvailableLocalesOf) {
+RUNTIME_FUNCTION(Runtime_AvailableLocalesOf) {
HandleScope scope(isolate);
+ Factory* factory = isolate->factory();
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
@@ -13802,7 +13786,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_AvailableLocalesOf) {
UErrorCode error = U_ZERO_ERROR;
char result[ULOC_FULLNAME_CAPACITY];
Handle<JSObject> locales =
- isolate->factory()->NewJSObject(isolate->object_function());
+ factory->NewJSObject(isolate->object_function());
for (int32_t i = 0; i < count; ++i) {
const char* icu_name = available_locales[i].getName();
@@ -13815,11 +13799,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_AvailableLocalesOf) {
continue;
}
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
locales,
- isolate->factory()->NewStringFromAscii(CStrVector(result)),
- isolate->factory()->NewNumber(i),
+ factory->NewStringFromAsciiChecked(result),
+ factory->NewNumber(i),
NONE));
}
@@ -13827,8 +13811,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_AvailableLocalesOf) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultICULocale) {
- SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_GetDefaultICULocale) {
+ HandleScope scope(isolate);
+ Factory* factory = isolate->factory();
ASSERT(args.length() == 0);
@@ -13840,31 +13825,34 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultICULocale) {
uloc_toLanguageTag(
default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
if (U_SUCCESS(status)) {
- return isolate->heap()->AllocateStringFromOneByte(CStrVector(result));
+ return *factory->NewStringFromAsciiChecked(result);
}
- return isolate->heap()->AllocateStringFromOneByte(CStrVector("und"));
+ return *factory->NewStringFromStaticAscii("und");
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLanguageTagVariants) {
+RUNTIME_FUNCTION(Runtime_GetLanguageTagVariants) {
HandleScope scope(isolate);
+ Factory* factory = isolate->factory();
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
uint32_t length = static_cast<uint32_t>(input->length()->Number());
- Handle<FixedArray> output = isolate->factory()->NewFixedArray(length);
- Handle<Name> maximized =
- isolate->factory()->NewStringFromAscii(CStrVector("maximized"));
- Handle<Name> base =
- isolate->factory()->NewStringFromAscii(CStrVector("base"));
+ // Set some limit to prevent fuzz tests from going OOM.
+ // Can be bumped when callers' requirements change.
+ RUNTIME_ASSERT(length < 100);
+ Handle<FixedArray> output = factory->NewFixedArray(length);
+ Handle<Name> maximized = factory->NewStringFromStaticAscii("maximized");
+ Handle<Name> base = factory->NewStringFromStaticAscii("base");
for (unsigned int i = 0; i < length; ++i) {
- Handle<Object> locale_id = Object::GetElement(isolate, input, i);
- RETURN_IF_EMPTY_HANDLE(isolate, locale_id);
+ Handle<Object> locale_id;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, locale_id, Object::GetElement(isolate, input, i));
if (!locale_id->IsString()) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
+ return isolate->Throw(*factory->illegal_argument_string());
}
v8::String::Utf8Value utf8_locale_id(
@@ -13879,7 +13867,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLanguageTagVariants) {
uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
&icu_locale_length, &error);
if (U_FAILURE(error) || icu_locale_length == 0) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
+ return isolate->Throw(*factory->illegal_argument_string());
}
// Maximize the locale.
@@ -13912,33 +13900,113 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLanguageTagVariants) {
icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error);
if (U_FAILURE(error)) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
+ return isolate->Throw(*factory->illegal_argument_string());
}
- Handle<JSObject> result =
- isolate->factory()->NewJSObject(isolate->object_function());
- RETURN_IF_EMPTY_HANDLE(isolate,
+ Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
result,
maximized,
- isolate->factory()->NewStringFromAscii(CStrVector(base_max_locale)),
+ factory->NewStringFromAsciiChecked(base_max_locale),
NONE));
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
result,
base,
- isolate->factory()->NewStringFromAscii(CStrVector(base_locale)),
+ factory->NewStringFromAsciiChecked(base_locale),
NONE));
output->set(i, *result);
}
- Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(output);
+ Handle<JSArray> result = factory->NewJSArrayWithElements(output);
result->set_length(Smi::FromInt(length));
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateDateTimeFormat) {
+RUNTIME_FUNCTION(Runtime_IsInitializedIntlObject) {
+ HandleScope scope(isolate);
+
+ ASSERT(args.length() == 1);
+
+ CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
+
+ if (!input->IsJSObject()) return isolate->heap()->false_value();
+ Handle<JSObject> obj = Handle<JSObject>::cast(input);
+
+ Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
+ Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
+ return isolate->heap()->ToBoolean(!tag->IsTheHole());
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsInitializedIntlObjectOfType) {
+ HandleScope scope(isolate);
+
+ ASSERT(args.length() == 2);
+
+ CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, expected_type, 1);
+
+ if (!input->IsJSObject()) return isolate->heap()->false_value();
+ Handle<JSObject> obj = Handle<JSObject>::cast(input);
+
+ Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
+ Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
+ return isolate->heap()->ToBoolean(
+ tag->IsString() && String::cast(*tag)->Equals(*expected_type));
+}
+
+
+RUNTIME_FUNCTION(Runtime_MarkAsInitializedIntlObjectOfType) {
+ HandleScope scope(isolate);
+
+ ASSERT(args.length() == 3);
+
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, impl, 2);
+
+ Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
+ JSObject::SetHiddenProperty(input, marker, type);
+
+ marker = isolate->factory()->intl_impl_object_string();
+ JSObject::SetHiddenProperty(input, marker, impl);
+
+ return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) {
+ HandleScope scope(isolate);
+
+ ASSERT(args.length() == 1);
+
+ CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
+
+ if (!input->IsJSObject()) {
+ Vector< Handle<Object> > arguments = HandleVector(&input, 1);
+ Handle<Object> type_error =
+ isolate->factory()->NewTypeError("not_intl_object", arguments);
+ return isolate->Throw(*type_error);
+ }
+
+ Handle<JSObject> obj = Handle<JSObject>::cast(input);
+
+ Handle<String> marker = isolate->factory()->intl_impl_object_string();
+ Handle<Object> impl(obj->GetHiddenProperty(marker), isolate);
+ if (impl->IsTheHole()) {
+ Vector< Handle<Object> > arguments = HandleVector(&obj, 1);
+ Handle<Object> type_error =
+ isolate->factory()->NewTypeError("not_intl_object", arguments);
+ return isolate->Throw(*type_error);
+ }
+ return *impl;
+}
+
+
+RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
@@ -13951,13 +14019,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateDateTimeFormat) {
I18N::GetTemplate(isolate);
// Create an empty object wrapper.
- bool has_pending_exception = false;
- Handle<JSObject> local_object = Execution::InstantiateObject(
- date_format_template, &has_pending_exception);
- if (has_pending_exception) {
- ASSERT(isolate->has_pending_exception());
- return Failure::Exception();
- }
+ Handle<JSObject> local_object;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, local_object,
+ Execution::InstantiateObject(date_format_template));
// Set date time formatter as internal field of the resulting JS object.
icu::SimpleDateFormat* date_format = DateFormat::InitializeDateTimeFormat(
@@ -13967,11 +14032,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateDateTimeFormat) {
local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
local_object,
- isolate->factory()->NewStringFromAscii(CStrVector("dateFormat")),
- isolate->factory()->NewStringFromAscii(CStrVector("valid")),
+ isolate->factory()->NewStringFromStaticAscii("dateFormat"),
+ isolate->factory()->NewStringFromStaticAscii("valid"),
NONE));
// Make object handle weak so we can delete the data format once GC kicks in.
@@ -13983,7 +14048,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateDateTimeFormat) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateFormat) {
+RUNTIME_FUNCTION(Runtime_InternalDateFormat) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -13991,13 +14056,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateFormat) {
CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
- bool has_pending_exception = false;
- Handle<Object> value =
- Execution::ToNumber(isolate, date, &has_pending_exception);
- if (has_pending_exception) {
- ASSERT(isolate->has_pending_exception());
- return Failure::Exception();
- }
+ Handle<Object> value;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, value, Execution::ToNumber(isolate, date));
icu::SimpleDateFormat* date_format =
DateFormat::UnpackDateFormat(isolate, date_format_holder);
@@ -14006,14 +14067,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateFormat) {
icu::UnicodeString result;
date_format->format(value->Number(), result);
- return *isolate->factory()->NewStringFromTwoByte(
- Vector<const uint16_t>(
- reinterpret_cast<const uint16_t*>(result.getBuffer()),
- result.length()));
+ Handle<String> result_str;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result_str,
+ isolate->factory()->NewStringFromTwoByte(
+ Vector<const uint16_t>(
+ reinterpret_cast<const uint16_t*>(result.getBuffer()),
+ result.length())));
+ return *result_str;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateParse) {
+RUNTIME_FUNCTION(Runtime_InternalDateParse) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -14031,19 +14096,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateParse) {
UDate date = date_format->parse(u_date, status);
if (U_FAILURE(status)) return isolate->heap()->undefined_value();
- bool has_pending_exception = false;
- Handle<JSDate> result = Handle<JSDate>::cast(
- Execution::NewDate(
- isolate, static_cast<double>(date), &has_pending_exception));
- if (has_pending_exception) {
- ASSERT(isolate->has_pending_exception());
- return Failure::Exception();
- }
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Execution::NewDate(isolate, static_cast<double>(date)));
+ ASSERT(result->IsJSDate());
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateNumberFormat) {
+RUNTIME_FUNCTION(Runtime_CreateNumberFormat) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
@@ -14056,13 +14118,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateNumberFormat) {
I18N::GetTemplate(isolate);
// Create an empty object wrapper.
- bool has_pending_exception = false;
- Handle<JSObject> local_object = Execution::InstantiateObject(
- number_format_template, &has_pending_exception);
- if (has_pending_exception) {
- ASSERT(isolate->has_pending_exception());
- return Failure::Exception();
- }
+ Handle<JSObject> local_object;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, local_object,
+ Execution::InstantiateObject(number_format_template));
// Set number formatter as internal field of the resulting JS object.
icu::DecimalFormat* number_format = NumberFormat::InitializeNumberFormat(
@@ -14072,11 +14131,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateNumberFormat) {
local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
local_object,
- isolate->factory()->NewStringFromAscii(CStrVector("numberFormat")),
- isolate->factory()->NewStringFromAscii(CStrVector("valid")),
+ isolate->factory()->NewStringFromStaticAscii("numberFormat"),
+ isolate->factory()->NewStringFromStaticAscii("valid"),
NONE));
Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
@@ -14087,7 +14146,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateNumberFormat) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberFormat) {
+RUNTIME_FUNCTION(Runtime_InternalNumberFormat) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -14095,13 +14154,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberFormat) {
CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
- bool has_pending_exception = false;
- Handle<Object> value = Execution::ToNumber(
- isolate, number, &has_pending_exception);
- if (has_pending_exception) {
- ASSERT(isolate->has_pending_exception());
- return Failure::Exception();
- }
+ Handle<Object> value;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, value, Execution::ToNumber(isolate, number));
icu::DecimalFormat* number_format =
NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
@@ -14110,14 +14165,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberFormat) {
icu::UnicodeString result;
number_format->format(value->Number(), result);
- return *isolate->factory()->NewStringFromTwoByte(
- Vector<const uint16_t>(
- reinterpret_cast<const uint16_t*>(result.getBuffer()),
- result.length()));
+ Handle<String> result_str;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result_str,
+ isolate->factory()->NewStringFromTwoByte(
+ Vector<const uint16_t>(
+ reinterpret_cast<const uint16_t*>(result.getBuffer()),
+ result.length())));
+ return *result_str;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberParse) {
+RUNTIME_FUNCTION(Runtime_InternalNumberParse) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -14156,7 +14215,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalNumberParse) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCollator) {
+RUNTIME_FUNCTION(Runtime_CreateCollator) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
@@ -14168,13 +14227,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCollator) {
Handle<ObjectTemplateInfo> collator_template = I18N::GetTemplate(isolate);
// Create an empty object wrapper.
- bool has_pending_exception = false;
- Handle<JSObject> local_object = Execution::InstantiateObject(
- collator_template, &has_pending_exception);
- if (has_pending_exception) {
- ASSERT(isolate->has_pending_exception());
- return Failure::Exception();
- }
+ Handle<JSObject> local_object;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, local_object, Execution::InstantiateObject(collator_template));
// Set collator as internal field of the resulting JS object.
icu::Collator* collator = Collator::InitializeCollator(
@@ -14184,11 +14239,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCollator) {
local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
local_object,
- isolate->factory()->NewStringFromAscii(CStrVector("collator")),
- isolate->factory()->NewStringFromAscii(CStrVector("valid")),
+ isolate->factory()->NewStringFromStaticAscii("collator"),
+ isolate->factory()->NewStringFromStaticAscii("valid"),
NONE));
Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
@@ -14199,7 +14254,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCollator) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalCompare) {
+RUNTIME_FUNCTION(Runtime_InternalCompare) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
@@ -14227,7 +14282,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalCompare) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringNormalize) {
+RUNTIME_FUNCTION(Runtime_StringNormalize) {
HandleScope scope(isolate);
static const UNormalizationMode normalizationForms[] =
{ UNORM_NFC, UNORM_NFD, UNORM_NFKC, UNORM_NFKD };
@@ -14236,6 +14291,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringNormalize) {
CONVERT_ARG_HANDLE_CHECKED(String, stringValue, 0);
CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]);
+ RUNTIME_ASSERT(form_id >= 0 &&
+ static_cast<size_t>(form_id) < ARRAY_SIZE(normalizationForms));
v8::String::Value string_value(v8::Utils::ToLocal(stringValue));
const UChar* u_value = reinterpret_cast<const UChar*>(*string_value);
@@ -14249,14 +14306,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringNormalize) {
return isolate->heap()->undefined_value();
}
- return *isolate->factory()->NewStringFromTwoByte(
- Vector<const uint16_t>(
- reinterpret_cast<const uint16_t*>(result.getBuffer()),
- result.length()));
+ Handle<String> result_str;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result_str,
+ isolate->factory()->NewStringFromTwoByte(
+ Vector<const uint16_t>(
+ reinterpret_cast<const uint16_t*>(result.getBuffer()),
+ result.length())));
+ return *result_str;
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateBreakIterator) {
+RUNTIME_FUNCTION(Runtime_CreateBreakIterator) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
@@ -14269,13 +14330,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateBreakIterator) {
I18N::GetTemplate2(isolate);
// Create an empty object wrapper.
- bool has_pending_exception = false;
- Handle<JSObject> local_object = Execution::InstantiateObject(
- break_iterator_template, &has_pending_exception);
- if (has_pending_exception) {
- ASSERT(isolate->has_pending_exception());
- return Failure::Exception();
- }
+ Handle<JSObject> local_object;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, local_object,
+ Execution::InstantiateObject(break_iterator_template));
// Set break iterator as internal field of the resulting JS object.
icu::BreakIterator* break_iterator = BreakIterator::InitializeBreakIterator(
@@ -14287,11 +14345,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateBreakIterator) {
// Make sure that the pointer to adopted text is NULL.
local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
local_object,
- isolate->factory()->NewStringFromAscii(CStrVector("breakIterator")),
- isolate->factory()->NewStringFromAscii(CStrVector("valid")),
+ isolate->factory()->NewStringFromStaticAscii("breakIterator"),
+ isolate->factory()->NewStringFromStaticAscii("valid"),
NONE));
// Make object handle weak so we can delete the break iterator once GC kicks
@@ -14304,7 +14362,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateBreakIterator) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorAdoptText) {
+RUNTIME_FUNCTION(Runtime_BreakIteratorAdoptText) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -14331,7 +14389,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorAdoptText) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorFirst) {
+RUNTIME_FUNCTION(Runtime_BreakIteratorFirst) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
@@ -14346,7 +14404,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorFirst) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorNext) {
+RUNTIME_FUNCTION(Runtime_BreakIteratorNext) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
@@ -14361,7 +14419,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorNext) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorCurrent) {
+RUNTIME_FUNCTION(Runtime_BreakIteratorCurrent) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
@@ -14376,7 +14434,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorCurrent) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorBreakType) {
+RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
@@ -14393,17 +14451,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_BreakIteratorBreakType) {
int32_t status = rule_based_iterator->getRuleStatus();
// Keep return values in sync with JavaScript BreakType enum.
if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
- return *isolate->factory()->NewStringFromAscii(CStrVector("none"));
+ return *isolate->factory()->NewStringFromStaticAscii("none");
} else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
- return *isolate->factory()->NewStringFromAscii(CStrVector("number"));
+ return *isolate->factory()->NewStringFromStaticAscii("number");
} else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
- return *isolate->factory()->NewStringFromAscii(CStrVector("letter"));
+ return *isolate->factory()->NewStringFromStaticAscii("letter");
} else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
- return *isolate->factory()->NewStringFromAscii(CStrVector("kana"));
+ return *isolate->factory()->NewStringFromStaticAscii("kana");
} else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
- return *isolate->factory()->NewStringFromAscii(CStrVector("ideo"));
+ return *isolate->factory()->NewStringFromStaticAscii("ideo");
} else {
- return *isolate->factory()->NewStringFromAscii(CStrVector("unknown"));
+ return *isolate->factory()->NewStringFromStaticAscii("unknown");
}
}
#endif // V8_I18N_SUPPORT
@@ -14441,14 +14499,14 @@ static Handle<Object> Runtime_GetScriptFromScriptName(
if (script.is_null()) return factory->undefined_value();
// Return the script found.
- return GetScriptWrapper(script);
+ return Script::GetWrapper(script);
}
// Get the script object from script data. NOTE: Regarding performance
// see the NOTE for GetScriptFromScriptData.
// args[0]: script data for the script to find the source for
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScript) {
+RUNTIME_FUNCTION(Runtime_GetScript) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
@@ -14465,11 +14523,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScript) {
// Collect the raw data for a stack trace. Returns an array of 4
// element segments each containing a receiver, function, code and
// native code offset.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectStackTrace) {
+RUNTIME_FUNCTION(Runtime_CollectStackTrace) {
HandleScope scope(isolate);
- ASSERT_EQ(args.length(), 3);
+ ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
- Handle<Object> caller = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1);
CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]);
// Optionally capture a more detailed stack trace for the message.
@@ -14481,12 +14539,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectStackTrace) {
// Retrieve the stack trace. This is the raw stack trace that yet has to
// be formatted. Since we only need this once, clear it afterwards.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAndClearOverflowedStackTrace) {
+RUNTIME_FUNCTION(Runtime_GetAndClearOverflowedStackTrace) {
HandleScope scope(isolate);
- ASSERT_EQ(args.length(), 1);
+ ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
Handle<String> key = isolate->factory()->hidden_stack_trace_string();
- Handle<Object> result(error_object->GetHiddenProperty(*key), isolate);
+ Handle<Object> result(error_object->GetHiddenProperty(key), isolate);
if (result->IsTheHole()) return isolate->heap()->undefined_value();
RUNTIME_ASSERT(result->IsJSArray() || result->IsUndefined());
JSObject::DeleteHiddenProperty(error_object, key);
@@ -14495,18 +14553,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAndClearOverflowedStackTrace) {
// Returns V8 version as a string.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) {
- SealHandleScope shs(isolate);
- ASSERT_EQ(args.length(), 0);
+RUNTIME_FUNCTION(Runtime_GetV8Version) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 0);
const char* version_string = v8::V8::GetVersion();
- return isolate->heap()->AllocateStringFromOneByte(CStrVector(version_string),
- NOT_TENURED);
+ return *isolate->factory()->NewStringFromAsciiChecked(version_string);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Abort) {
+RUNTIME_FUNCTION(Runtime_Abort) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_SMI_ARG_CHECKED(message_id, 0);
@@ -14520,7 +14577,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Abort) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_AbortJS) {
+RUNTIME_FUNCTION(Runtime_AbortJS) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
@@ -14532,16 +14589,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_AbortJS) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_FlattenString) {
+RUNTIME_FUNCTION(Runtime_FlattenString) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
- FlattenString(str);
- return isolate->heap()->undefined_value();
+ return *String::Flatten(str);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyContextDisposed) {
+RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
HandleScope scope(isolate);
ASSERT(args.length() == 0);
isolate->heap()->NotifyContextDisposed();
@@ -14549,7 +14605,25 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyContextDisposed) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_TryMigrateInstance) {
+RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
+ int idx = index->value() >> 1;
+ int inobject_properties = object->map()->inobject_properties();
+ if (idx < 0) {
+ idx = -idx + inobject_properties - 1;
+ }
+ int max_idx = object->properties()->length() + inobject_properties;
+ RUNTIME_ASSERT(idx < max_idx);
+ Handle<Object> raw_value(object->RawFastPropertyAt(idx), isolate);
+ RUNTIME_ASSERT(raw_value->IsNumber() || raw_value->IsUninitialized());
+ return *Object::NewStorageFor(isolate, raw_value, Representation::Double());
+}
+
+
+RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
@@ -14560,43 +14634,46 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TryMigrateInstance) {
// code where we can't handle lazy deopts for lack of a suitable bailout
// ID. So we just try migration and signal failure if necessary,
// which will also trigger a deopt.
- Handle<Object> result = JSObject::TryMigrateInstance(js_object);
- if (result.is_null()) return Smi::FromInt(0);
+ if (!JSObject::TryMigrateInstance(js_object)) return Smi::FromInt(0);
return *object;
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_GetFromCache) {
+RUNTIME_FUNCTION(RuntimeHidden_GetFromCache) {
SealHandleScope shs(isolate);
// This is only called from codegen, so checks might be more lax.
CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
- Object* key = args[1];
+ CONVERT_ARG_CHECKED(Object, key, 1);
- int finger_index = cache->finger_index();
- Object* o = cache->get(finger_index);
- if (o == key) {
- // The fastest case: hit the same place again.
- return cache->get(finger_index + 1);
- }
+ {
+ DisallowHeapAllocation no_alloc;
- for (int i = finger_index - 2;
- i >= JSFunctionResultCache::kEntriesIndex;
- i -= 2) {
- o = cache->get(i);
+ int finger_index = cache->finger_index();
+ Object* o = cache->get(finger_index);
if (o == key) {
- cache->set_finger_index(i);
- return cache->get(i + 1);
+ // The fastest case: hit the same place again.
+ return cache->get(finger_index + 1);
}
- }
- int size = cache->size();
- ASSERT(size <= cache->length());
+ for (int i = finger_index - 2;
+ i >= JSFunctionResultCache::kEntriesIndex;
+ i -= 2) {
+ o = cache->get(i);
+ if (o == key) {
+ cache->set_finger_index(i);
+ return cache->get(i + 1);
+ }
+ }
- for (int i = size - 2; i > finger_index; i -= 2) {
- o = cache->get(i);
- if (o == key) {
- cache->set_finger_index(i);
- return cache->get(i + 1);
+ int size = cache->size();
+ ASSERT(size <= cache->length());
+
+ for (int i = size - 2; i > finger_index; i -= 2) {
+ o = cache->get(i);
+ if (o == key) {
+ cache->set_finger_index(i);
+ return cache->get(i + 1);
+ }
}
}
@@ -14614,14 +14691,9 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_GetFromCache) {
isolate);
// This handle is nor shared, nor used later, so it's safe.
Handle<Object> argv[] = { key_handle };
- bool pending_exception;
- value = Execution::Call(isolate,
- factory,
- receiver,
- ARRAY_SIZE(argv),
- argv,
- &pending_exception);
- if (pending_exception) return Failure::Exception();
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, value,
+ Execution::Call(isolate, factory, receiver, ARRAY_SIZE(argv), argv));
}
#ifdef VERIFY_HEAP
@@ -14631,8 +14703,8 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_GetFromCache) {
#endif
// Function invocation may have cleared the cache. Reread all the data.
- finger_index = cache_handle->finger_index();
- size = cache_handle->size();
+ int finger_index = cache_handle->finger_index();
+ int size = cache_handle->size();
// If we have spare room, put new data into it, otherwise evict post finger
// entry which is likely to be the least recently used.
@@ -14665,15 +14737,17 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_GetFromCache) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetStartPosition) {
+RUNTIME_FUNCTION(Runtime_MessageGetStartPosition) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
return Smi::FromInt(message->start_position());
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetScript) {
+RUNTIME_FUNCTION(Runtime_MessageGetScript) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
return message->script();
}
@@ -14682,7 +14756,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetScript) {
#ifdef DEBUG
// ListNatives is ONLY used by the fuzz-natives.js in debug mode
// Exclude the code in release mode.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ListNatives) {
+RUNTIME_FUNCTION(Runtime_ListNatives) {
HandleScope scope(isolate);
ASSERT(args.length() == 0);
#define COUNT_ENTRY(Name, argc, ressize) + 1
@@ -14701,11 +14775,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ListNatives) {
Handle<String> name; \
/* Inline runtime functions have an underscore in front of the name. */ \
if (inline_runtime_functions) { \
- name = factory->NewStringFromAscii( \
- Vector<const char>("_" #Name, StrLength("_" #Name))); \
+ name = factory->NewStringFromStaticAscii("_" #Name); \
} else { \
- name = factory->NewStringFromAscii( \
- Vector<const char>(#Name, StrLength(#Name))); \
+ name = factory->NewStringFromStaticAscii(#Name); \
} \
Handle<FixedArray> pair_elements = factory->NewFixedArray(2); \
pair_elements->set(0, *name); \
@@ -14727,28 +14799,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ListNatives) {
#endif
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_Log) {
- HandleScope handle_scope(isolate);
- ASSERT(args.length() == 2);
- CONVERT_ARG_HANDLE_CHECKED(String, format, 0);
- CONVERT_ARG_HANDLE_CHECKED(JSArray, elms, 1);
-
- SmartArrayPointer<char> format_chars = format->ToCString();
- isolate->logger()->LogRuntime(
- Vector<const char>(format_chars.get(), format->length()), elms);
- return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) {
+RUNTIME_FUNCTION(Runtime_IS_VAR) {
UNREACHABLE(); // implemented as macro in the parser
return NULL;
}
#define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \
- RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \
- CONVERT_ARG_CHECKED(JSObject, obj, 0); \
+ RUNTIME_FUNCTION(Runtime_Has##Name) { \
+ CONVERT_ARG_CHECKED(JSObject, obj, 0); \
return isolate->heap()->ToBoolean(obj->Has##Name()); \
}
@@ -14767,7 +14826,7 @@ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
#define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size) \
- RUNTIME_FUNCTION(MaybeObject*, Runtime_HasExternal##Type##Elements) { \
+ RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) { \
CONVERT_ARG_CHECKED(JSObject, obj, 0); \
return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements()); \
}
@@ -14778,7 +14837,7 @@ TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
#define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s) \
- RUNTIME_FUNCTION(MaybeObject*, Runtime_HasFixed##Type##Elements) { \
+ RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) { \
CONVERT_ARG_CHECKED(JSObject, obj, 0); \
return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements()); \
}
@@ -14788,7 +14847,7 @@ TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
#undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
-RUNTIME_FUNCTION(MaybeObject*, Runtime_HaveSameMap) {
+RUNTIME_FUNCTION(Runtime_HaveSameMap) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_CHECKED(JSObject, obj1, 0);
@@ -14797,52 +14856,40 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_HaveSameMap) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsAccessCheckNeeded) {
+RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(HeapObject, obj, 0);
- return isolate->heap()->ToBoolean(obj->IsAccessCheckNeeded());
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsObserved) {
+RUNTIME_FUNCTION(Runtime_IsObserved) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
- JSReceiver* obj = JSReceiver::cast(args[0]);
- if (obj->IsJSGlobalProxy()) {
- Object* proto = obj->GetPrototype();
- if (proto->IsNull()) return isolate->heap()->false_value();
- ASSERT(proto->IsJSGlobalObject());
- obj = JSReceiver::cast(proto);
- }
+ CONVERT_ARG_CHECKED(JSReceiver, obj, 0);
+ ASSERT(!obj->IsJSGlobalProxy() || !obj->map()->is_observed());
return isolate->heap()->ToBoolean(obj->map()->is_observed());
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetIsObserved) {
+RUNTIME_FUNCTION(Runtime_SetIsObserved) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
- if (obj->IsJSGlobalProxy()) {
- Object* proto = obj->GetPrototype();
- if (proto->IsNull()) return isolate->heap()->undefined_value();
- ASSERT(proto->IsJSGlobalObject());
- obj = handle(JSReceiver::cast(proto));
- }
+ ASSERT(!obj->IsJSGlobalProxy());
if (obj->IsJSProxy())
return isolate->heap()->undefined_value();
- ASSERT(!(obj->map()->is_observed() && obj->IsJSObject() &&
- Handle<JSObject>::cast(obj)->HasFastElements()));
ASSERT(obj->IsJSObject());
JSObject::SetObserved(Handle<JSObject>::cast(obj));
return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetMicrotaskPending) {
+RUNTIME_FUNCTION(Runtime_SetMicrotaskPending) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
CONVERT_BOOLEAN_ARG_CHECKED(new_state, 0);
@@ -14852,30 +14899,29 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetMicrotaskPending) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_RunMicrotasks) {
+RUNTIME_FUNCTION(Runtime_RunMicrotasks) {
HandleScope scope(isolate);
ASSERT(args.length() == 0);
- if (isolate->microtask_pending())
- Execution::RunMicrotasks(isolate);
+ if (isolate->microtask_pending()) Execution::RunMicrotasks(isolate);
return isolate->heap()->undefined_value();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetMicrotaskState) {
+RUNTIME_FUNCTION(Runtime_GetMicrotaskState) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 0);
return isolate->heap()->microtask_state();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetObservationState) {
+RUNTIME_FUNCTION(Runtime_GetObservationState) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 0);
return isolate->heap()->observation_state();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ObservationWeakMapCreate) {
+RUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) {
HandleScope scope(isolate);
ASSERT(args.length() == 0);
// TODO(adamk): Currently this runtime function is only called three times per
@@ -14885,53 +14931,108 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ObservationWeakMapCreate) {
isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
Handle<JSWeakMap> weakmap =
Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
- return WeakCollectionInitialize(isolate, weakmap);
+ return *WeakCollectionInitialize(isolate, weakmap);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_UnwrapGlobalProxy) {
- SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
- Object* object = args[0];
- if (object->IsJSGlobalProxy()) {
- object = object->GetPrototype(isolate);
- if (object->IsNull()) return isolate->heap()->undefined_value();
- }
- return object;
+static bool ContextsHaveSameOrigin(Handle<Context> context1,
+ Handle<Context> context2) {
+ return context1->security_token() == context2->security_token();
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_IsAccessAllowedForObserver) {
+RUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
- ASSERT(object->map()->is_access_check_needed());
- Handle<Object> key = args.at<Object>(2);
- SaveContext save(isolate);
- isolate->set_context(observer->context());
- if (!isolate->MayNamedAccessWrapper(object,
- isolate->factory()->undefined_value(),
- v8::ACCESS_KEYS)) {
- return isolate->heap()->false_value();
- }
- bool access_allowed = false;
- uint32_t index = 0;
- if (key->ToArrayIndex(&index) ||
- (key->IsString() && String::cast(*key)->AsArrayIndex(&index))) {
- access_allowed =
- isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_GET) &&
- isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_HAS);
- } else {
- access_allowed =
- isolate->MayNamedAccessWrapper(object, key, v8::ACCESS_GET) &&
- isolate->MayNamedAccessWrapper(object, key, v8::ACCESS_HAS);
- }
- return isolate->heap()->ToBoolean(access_allowed);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, record, 2);
+
+ Handle<Context> observer_context(observer->context()->native_context(),
+ isolate);
+ Handle<Context> object_context(object->GetCreationContext());
+ Handle<Context> record_context(record->GetCreationContext());
+
+ return isolate->heap()->ToBoolean(
+ ContextsHaveSameOrigin(object_context, observer_context) &&
+ ContextsHaveSameOrigin(object_context, record_context));
+}
+
+
+RUNTIME_FUNCTION(Runtime_ObjectWasCreatedInCurrentOrigin) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+
+ Handle<Context> creation_context(object->GetCreationContext(), isolate);
+ return isolate->heap()->ToBoolean(
+ ContextsHaveSameOrigin(creation_context, isolate->native_context()));
+}
+
+
+RUNTIME_FUNCTION(Runtime_ObjectObserveInObjectContext) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, accept, 2);
+ RUNTIME_ASSERT(accept->IsUndefined() || accept->IsJSObject());
+
+ Handle<Context> context(object->GetCreationContext(), isolate);
+ Handle<JSFunction> function(context->native_object_observe(), isolate);
+ Handle<Object> call_args[] = { object, callback, accept };
+ Handle<Object> result;
+
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Execution::Call(isolate, function,
+ handle(context->object_function(), isolate),
+ ARRAY_SIZE(call_args), call_args, true));
+ return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_ObjectGetNotifierInObjectContext) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+
+ Handle<Context> context(object->GetCreationContext(), isolate);
+ Handle<JSFunction> function(context->native_object_get_notifier(), isolate);
+ Handle<Object> call_args[] = { object };
+ Handle<Object> result;
+
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Execution::Call(isolate, function,
+ handle(context->object_function(), isolate),
+ ARRAY_SIZE(call_args), call_args, true));
+ return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_ObjectNotifierPerformChangeInObjectContext) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, change_type, 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, change_fn, 2);
+
+ Handle<Context> context(object_info->GetCreationContext(), isolate);
+ Handle<JSFunction> function(context->native_object_notifier_perform_change(),
+ isolate);
+ Handle<Object> call_args[] = { object_info, change_type, change_fn };
+ Handle<Object> result;
+
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ Execution::Call(isolate, function, isolate->factory()->undefined_value(),
+ ARRAY_SIZE(call_args), call_args, true));
+ return *result;
}
-static MaybeObject* ArrayConstructorCommon(Isolate* isolate,
+static Object* ArrayConstructorCommon(Isolate* isolate,
Handle<JSFunction> constructor,
Handle<AllocationSite> site,
Arguments* caller_args) {
@@ -14970,7 +15071,6 @@ static MaybeObject* ArrayConstructorCommon(Isolate* isolate,
Handle<Map> initial_map(constructor->initial_map(), isolate);
if (to_kind != initial_map->elements_kind()) {
initial_map = Map::AsElementsKind(initial_map, to_kind);
- RETURN_IF_EMPTY_HANDLE(isolate, initial_map);
}
// If we don't care to track arrays of to_kind ElementsKind, then
@@ -14996,8 +15096,8 @@ static MaybeObject* ArrayConstructorCommon(Isolate* isolate,
factory->NewJSArrayStorage(array, 0, 0, DONT_INITIALIZE_ARRAY_ELEMENTS);
ElementsKind old_kind = array->GetElementsKind();
- RETURN_IF_EMPTY_HANDLE(isolate,
- ArrayConstructInitializeElements(array, caller_args));
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, ArrayConstructInitializeElements(array, caller_args));
if (!site.is_null() &&
(old_kind != array->GetElementsKind() ||
!can_use_type_feedback)) {
@@ -15010,7 +15110,7 @@ static MaybeObject* ArrayConstructorCommon(Isolate* isolate,
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_ArrayConstructor) {
+RUNTIME_FUNCTION(RuntimeHidden_ArrayConstructor) {
HandleScope scope(isolate);
// If we get 2 arguments then they are the stub parameters (constructor, type
// info). If we get 4, then the first one is a pointer to the arguments
@@ -15047,7 +15147,7 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_ArrayConstructor) {
}
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_InternalArrayConstructor) {
+RUNTIME_FUNCTION(RuntimeHidden_InternalArrayConstructor) {
HandleScope scope(isolate);
Arguments empty_args(0, NULL);
bool no_caller_args = args.length() == 1;
@@ -15070,7 +15170,8 @@ RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_InternalArrayConstructor) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_MaxSmi) {
+RUNTIME_FUNCTION(Runtime_MaxSmi) {
+ ASSERT(args.length() == 0);
return Smi::FromInt(Smi::kMaxValue);
}
@@ -15111,37 +15212,27 @@ static const Runtime::Function kIntrinsicFunctions[] = {
#undef F
-MaybeObject* Runtime::InitializeIntrinsicFunctionNames(Heap* heap,
- Object* dictionary) {
- ASSERT(dictionary != NULL);
- ASSERT(NameDictionary::cast(dictionary)->NumberOfElements() == 0);
+void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate,
+ Handle<NameDictionary> dict) {
+ ASSERT(dict->NumberOfElements() == 0);
+ HandleScope scope(isolate);
for (int i = 0; i < kNumFunctions; ++i) {
const char* name = kIntrinsicFunctions[i].name;
if (name == NULL) continue;
- Object* name_string;
- { MaybeObject* maybe_name_string =
- heap->InternalizeUtf8String(name);
- if (!maybe_name_string->ToObject(&name_string)) return maybe_name_string;
- }
- NameDictionary* name_dictionary = NameDictionary::cast(dictionary);
- { MaybeObject* maybe_dictionary = name_dictionary->Add(
- String::cast(name_string),
- Smi::FromInt(i),
- PropertyDetails(NONE, NORMAL, Representation::None()));
- if (!maybe_dictionary->ToObject(&dictionary)) {
- // Non-recoverable failure. Calling code must restart heap
- // initialization.
- return maybe_dictionary;
- }
- }
+ Handle<NameDictionary> new_dict = NameDictionary::Add(
+ dict,
+ isolate->factory()->InternalizeUtf8String(name),
+ Handle<Smi>(Smi::FromInt(i), isolate),
+ PropertyDetails(NONE, NORMAL, Representation::None()));
+ // The dictionary does not need to grow.
+ CHECK(new_dict.is_identical_to(dict));
}
- return dictionary;
}
const Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
Heap* heap = name->GetHeap();
- int entry = heap->intrinsic_function_names()->FindEntry(*name);
+ int entry = heap->intrinsic_function_names()->FindEntry(name);
if (entry != kNotFound) {
Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
int function_index = Smi::cast(smi_index)->value();
@@ -15155,31 +15246,4 @@ const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
return &(kIntrinsicFunctions[static_cast<int>(id)]);
}
-
-void Runtime::PerformGC(Object* result, Isolate* isolate) {
- Failure* failure = Failure::cast(result);
- if (failure->IsRetryAfterGC()) {
- if (isolate->heap()->new_space()->AddFreshPage()) {
- return;
- }
-
- // Try to do a garbage collection; ignore it if it fails. The C
- // entry stub will throw an out-of-memory exception in that case.
- isolate->heap()->CollectGarbage(failure->allocation_space(),
- "Runtime::PerformGC");
- } else {
- // Handle last resort GC and make sure to allow future allocations
- // to grow the heap without causing GCs (if possible).
- isolate->counters()->gc_last_resort_from_js()->Increment();
- isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
- "Runtime::PerformGC");
- }
-}
-
-
-void Runtime::OutOfMemory() {
- Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true);
- UNREACHABLE();
-}
-
} } // namespace v8::internal
diff --git a/deps/v8/src/runtime.h b/deps/v8/src/runtime.h
index 58cd5259c9..38d2126f0e 100644
--- a/deps/v8/src/runtime.h
+++ b/deps/v8/src/runtime.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_RUNTIME_H_
#define V8_RUNTIME_H_
@@ -97,9 +74,11 @@ namespace internal {
F(SetNativeFlag, 1, 1) \
F(SetInlineBuiltinFlag, 1, 1) \
F(StoreArrayLiteralElement, 5, 1) \
- F(DebugCallbackSupportsStepping, 1, 1) \
F(DebugPrepareStepInIfStepping, 1, 1) \
+ F(DebugPromiseHandlePrologue, 1, 1) \
+ F(DebugPromiseHandleEpilogue, 0, 1) \
F(FlattenString, 1, 1) \
+ F(LoadMutableDouble, 2, 1) \
F(TryMigrateInstance, 1, 1) \
F(NotifyContextDisposed, 0, 1) \
\
@@ -133,7 +112,6 @@ namespace internal {
F(NumberDiv, 2, 1) \
F(NumberMod, 2, 1) \
F(NumberUnaryMinus, 1, 1) \
- F(NumberAlloc, 0, 1) \
F(NumberImul, 2, 1) \
\
F(StringBuilderConcat, 3, 1) \
@@ -157,18 +135,14 @@ namespace internal {
F(SmiLexicographicCompare, 2, 1) \
\
/* Math */ \
- F(Math_acos, 1, 1) \
- F(Math_asin, 1, 1) \
- F(Math_atan, 1, 1) \
- F(Math_log, 1, 1) \
- F(Math_sqrt, 1, 1) \
- F(Math_exp, 1, 1) \
- F(Math_floor, 1, 1) \
- F(Math_pow, 2, 1) \
- F(Math_pow_cfunction, 2, 1) \
- F(Math_atan2, 2, 1) \
+ F(MathAcos, 1, 1) \
+ F(MathAsin, 1, 1) \
+ F(MathAtan, 1, 1) \
+ F(MathFloor, 1, 1) \
+ F(MathAtan2, 2, 1) \
+ F(MathExp, 1, 1) \
F(RoundNumber, 1, 1) \
- F(Math_fround, 1, 1) \
+ F(MathFround, 1, 1) \
\
/* Regular expressions */ \
F(RegExpCompile, 3, 1) \
@@ -229,7 +203,7 @@ namespace internal {
F(SetCode, 2, 1) \
F(SetExpectedNumberOfProperties, 2, 1) \
\
- F(CreateApiFunction, 1, 1) \
+ F(CreateApiFunction, 2, 1) \
F(IsTemplate, 1, 1) \
F(GetTemplateField, 2, 1) \
F(DisableAccessChecks, 1, 1) \
@@ -301,15 +275,25 @@ namespace internal {
F(SetAdd, 2, 1) \
F(SetHas, 2, 1) \
F(SetDelete, 2, 1) \
+ F(SetClear, 1, 1) \
F(SetGetSize, 1, 1) \
+ F(SetCreateIterator, 2, 1) \
+ \
+ F(SetIteratorNext, 1, 1) \
+ F(SetIteratorClose, 1, 1) \
\
/* Harmony maps */ \
F(MapInitialize, 1, 1) \
F(MapGet, 2, 1) \
F(MapHas, 2, 1) \
F(MapDelete, 2, 1) \
+ F(MapClear, 1, 1) \
F(MapSet, 3, 1) \
F(MapGetSize, 1, 1) \
+ F(MapCreateIterator, 2, 1) \
+ \
+ F(MapIteratorNext, 1, 1) \
+ F(MapIteratorClose, 1, 1) \
\
/* Harmony weak maps and sets */ \
F(WeakCollectionInitialize, 1, 1) \
@@ -327,26 +311,23 @@ namespace internal {
F(SetIsObserved, 1, 1) \
F(GetObservationState, 0, 1) \
F(ObservationWeakMapCreate, 0, 1) \
- F(UnwrapGlobalProxy, 1, 1) \
- F(IsAccessAllowedForObserver, 3, 1) \
+ F(ObserverObjectAndRecordHaveSameOrigin, 3, 1) \
+ F(ObjectWasCreatedInCurrentOrigin, 1, 1) \
+ F(ObjectObserveInObjectContext, 3, 1) \
+ F(ObjectGetNotifierInObjectContext, 1, 1) \
+ F(ObjectNotifierPerformChangeInObjectContext, 3, 1) \
\
/* Harmony typed arrays */ \
F(ArrayBufferInitialize, 2, 1)\
- F(ArrayBufferGetByteLength, 1, 1)\
F(ArrayBufferSliceImpl, 3, 1) \
F(ArrayBufferIsView, 1, 1) \
F(ArrayBufferNeuter, 1, 1) \
\
F(TypedArrayInitializeFromArrayLike, 4, 1) \
F(TypedArrayGetBuffer, 1, 1) \
- F(TypedArrayGetByteLength, 1, 1) \
- F(TypedArrayGetByteOffset, 1, 1) \
- F(TypedArrayGetLength, 1, 1) \
F(TypedArraySetFastCases, 3, 1) \
\
F(DataViewGetBuffer, 1, 1) \
- F(DataViewGetByteLength, 1, 1) \
- F(DataViewGetByteOffset, 1, 1) \
F(DataViewGetInt8, 3, 1) \
F(DataViewGetUint8, 3, 1) \
F(DataViewGetInt16, 3, 1) \
@@ -420,11 +401,10 @@ namespace internal {
F(HasFastProperties, 1, 1) \
F(TransitionElementsKind, 2, 1) \
F(HaveSameMap, 2, 1) \
- F(IsAccessCheckNeeded, 1, 1)
+ F(IsJSGlobalProxy, 1, 1)
-#ifdef ENABLE_DEBUGGER_SUPPORT
-#define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F) \
+#define RUNTIME_FUNCTION_LIST_DEBUGGER(F) \
/* Debugger support*/ \
F(DebugBreak, 0, 1) \
F(SetDebugEventListener, 2, 1) \
@@ -487,10 +467,6 @@ namespace internal {
F(CollectGarbage, 1, 1) \
F(GetHeapUsage, 0, 1) \
-#else
-#define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
-#endif
-
#ifdef V8_I18N_SUPPORT
#define RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F) \
@@ -500,6 +476,10 @@ namespace internal {
F(AvailableLocalesOf, 1, 1) \
F(GetDefaultICULocale, 0, 1) \
F(GetLanguageTagVariants, 1, 1) \
+ F(IsInitializedIntlObject, 1, 1) \
+ F(IsInitializedIntlObjectOfType, 2, 1) \
+ F(MarkAsInitializedIntlObjectOfType, 3, 1) \
+ F(GetImplFromInitializedIntlObject, 1, 1) \
\
/* Date format and parse. */ \
F(CreateDateTimeFormat, 3, 1) \
@@ -549,13 +529,14 @@ namespace internal {
RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \
RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
RUNTIME_FUNCTION_LIST_DEBUG(F) \
- RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F) \
+ RUNTIME_FUNCTION_LIST_DEBUGGER(F) \
RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F)
// RUNTIME_HIDDEN_FUNCTION_LIST defines all runtime functions accessed
// by id from code generator, but not via native call by name.
// Entries have the form F(name, number of arguments, number of return values).
#define RUNTIME_HIDDEN_FUNCTION_LIST(F) \
+ /* String and Regexp */ \
F(NumberToString, 1, 1) \
F(RegExpConstructResult, 3, 1) \
F(RegExpExec, 4, 1) \
@@ -563,7 +544,6 @@ namespace internal {
F(SubString, 3, 1) \
F(StringCompare, 2, 1) \
F(StringCharCodeAt, 2, 1) \
- F(Log, 3, 1) \
F(GetFromCache, 2, 1) \
\
/* Compilation */ \
@@ -634,7 +614,11 @@ namespace internal {
F(InitializeConstContextSlot, 3, 1) \
\
/* Eval */ \
- F(ResolvePossiblyDirectEval, 5, 2)
+ F(ResolvePossiblyDirectEval, 5, 2) \
+ \
+ /* Maths */ \
+ F(MathPowSlow, 2, 1) \
+ F(MathPow, 2, 1)
// ----------------------------------------------------------------------------
// INLINE_FUNCTION_LIST defines all inlined functions accessed
@@ -663,8 +647,6 @@ namespace internal {
F(IsSpecObject, 1, 1) \
F(IsStringWrapperSafeForDefaultValueOf, 1, 1) \
F(MathPow, 2, 1) \
- F(MathSqrt, 1, 1) \
- F(MathLog, 1, 1) \
F(IsMinusZero, 1, 1) \
F(HasCachedArrayIndex, 1, 1) \
F(GetCachedArrayIndex, 1, 1) \
@@ -674,7 +656,6 @@ namespace internal {
F(DebugBreakInOptimizedCode, 0, 1) \
F(ClassOf, 1, 1) \
F(StringCharCodeAt, 2, 1) \
- F(Log, 3, 1) \
F(StringAdd, 2, 1) \
F(SubString, 3, 1) \
F(StringCompare, 2, 1) \
@@ -690,13 +671,24 @@ namespace internal {
// a corresponding runtime function, that is called from non-optimized code.
// Entries have the form F(name, number of arguments, number of return values).
#define INLINE_OPTIMIZED_FUNCTION_LIST(F) \
- F(DoubleHi, 1, 1) \
- F(DoubleLo, 1, 1) \
- F(ConstructDouble, 2, 1) \
+ /* Typed Arrays */ \
F(TypedArrayInitialize, 5, 1) \
F(DataViewInitialize, 4, 1) \
F(MaxSmi, 0, 1) \
- F(TypedArrayMaxSizeInHeap, 0, 1)
+ F(TypedArrayMaxSizeInHeap, 0, 1) \
+ F(ArrayBufferViewGetByteLength, 1, 1) \
+ F(ArrayBufferViewGetByteOffset, 1, 1) \
+ F(TypedArrayGetLength, 1, 1) \
+ /* ArrayBuffer */ \
+ F(ArrayBufferGetByteLength, 1, 1) \
+ /* Maths */ \
+ F(ConstructDouble, 2, 1) \
+ F(DoubleHi, 1, 1) \
+ F(DoubleLo, 1, 1) \
+ F(MathSqrt, 1, 1) \
+ F(MathLog, 1, 1) \
+ /* Debugger */ \
+ F(DebugCallbackSupportsStepping, 1, 1)
//---------------------------------------------------------------------------
@@ -791,11 +783,8 @@ class Runtime : public AllStatic {
// Add internalized strings for all the intrinsic function names to a
// StringDictionary.
- // Returns failure if an allocation fails. In this case, it must be
- // retried with a new, empty StringDictionary, not with the same one.
- // Alternatively, heap initialization can be completely restarted.
- MUST_USE_RESULT static MaybeObject* InitializeIntrinsicFunctionNames(
- Heap* heap, Object* dictionary);
+ static void InitializeIntrinsicFunctionNames(Isolate* isolate,
+ Handle<NameDictionary> dict);
// Get the intrinsic function with the given name, which must be internalized.
static const Function* FunctionForName(Handle<String> name);
@@ -816,11 +805,12 @@ class Runtime : public AllStatic {
// Support getting the characters in a string using [] notation as
// in Firefox/SpiderMonkey, Safari and Opera.
- static Handle<Object> GetElementOrCharAt(Isolate* isolate,
- Handle<Object> object,
- uint32_t index);
+ MUST_USE_RESULT static MaybeHandle<Object> GetElementOrCharAt(
+ Isolate* isolate,
+ Handle<Object> object,
+ uint32_t index);
- static Handle<Object> SetObjectProperty(
+ MUST_USE_RESULT static MaybeHandle<Object> SetObjectProperty(
Isolate* isolate,
Handle<Object> object,
Handle<Object> key,
@@ -828,30 +818,26 @@ class Runtime : public AllStatic {
PropertyAttributes attr,
StrictMode strict_mode);
- static Handle<Object> ForceSetObjectProperty(
- Isolate* isolate,
+ MUST_USE_RESULT static MaybeHandle<Object> ForceSetObjectProperty(
Handle<JSObject> object,
Handle<Object> key,
Handle<Object> value,
- PropertyAttributes attr);
+ PropertyAttributes attr,
+ JSReceiver::StoreFromKeyed store_from_keyed
+ = JSReceiver::MAY_BE_STORE_FROM_KEYED);
- MUST_USE_RESULT static MaybeObject* DeleteObjectProperty(
+ MUST_USE_RESULT static MaybeHandle<Object> DeleteObjectProperty(
Isolate* isolate,
Handle<JSReceiver> object,
Handle<Object> key,
JSReceiver::DeleteMode mode);
- MUST_USE_RESULT static MaybeObject* HasObjectProperty(
+ MUST_USE_RESULT static MaybeHandle<Object> HasObjectProperty(
Isolate* isolate,
Handle<JSReceiver> object,
Handle<Object> key);
- MUST_USE_RESULT static MaybeObject* GetObjectProperty(
- Isolate* isolate,
- Handle<Object> object,
- Handle<Object> key);
-
- MUST_USE_RESULT static MaybeObject* GetObjectPropertyOrFail(
+ MUST_USE_RESULT static MaybeHandle<Object> GetObjectProperty(
Isolate* isolate,
Handle<Object> object,
Handle<Object> key);
@@ -884,7 +870,10 @@ class Runtime : public AllStatic {
ARRAY_ID_INT32 = 6,
ARRAY_ID_FLOAT32 = 7,
ARRAY_ID_FLOAT64 = 8,
- ARRAY_ID_UINT8_CLAMPED = 9
+ ARRAY_ID_UINT8_CLAMPED = 9,
+
+ ARRAY_ID_FIRST = ARRAY_ID_UINT8,
+ ARRAY_ID_LAST = ARRAY_ID_UINT8_CLAMPED
};
static void ArrayIdToTypeAndSize(int array_id,
@@ -893,12 +882,8 @@ class Runtime : public AllStatic {
ElementsKind* fixed_elements_kind,
size_t *element_size);
- // Helper functions used stubs.
- static void PerformGC(Object* result, Isolate* isolate);
- static void OutOfMemory();
-
// Used in runtime.cc and hydrogen's VisitArrayLiteral.
- static Handle<Object> CreateArrayLiteralBoilerplate(
+ MUST_USE_RESULT static MaybeHandle<Object> CreateArrayLiteralBoilerplate(
Isolate* isolate,
Handle<FixedArray> literals,
Handle<FixedArray> elements);
diff --git a/deps/v8/src/runtime.js b/deps/v8/src/runtime.js
index a49bc8448d..1dee2e08f6 100644
--- a/deps/v8/src/runtime.js
+++ b/deps/v8/src/runtime.js
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This files contains runtime support implemented in JavaScript.
@@ -464,7 +441,7 @@ function APPLY_PREPARE(args) {
}
-function APPLY_OVERFLOW(length) {
+function STACK_OVERFLOW(length) {
throw %MakeRangeError('stack_overflow', []);
}
diff --git a/deps/v8/src/safepoint-table.cc b/deps/v8/src/safepoint-table.cc
index beecb27582..b7833c232b 100644
--- a/deps/v8/src/safepoint-table.cc
+++ b/deps/v8/src/safepoint-table.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/safepoint-table.h b/deps/v8/src/safepoint-table.h
index cd094c55bf..5a1af55cb1 100644
--- a/deps/v8/src/safepoint-table.h
+++ b/deps/v8/src/safepoint-table.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_SAFEPOINT_TABLE_H_
#define V8_SAFEPOINT_TABLE_H_
diff --git a/deps/v8/src/sampler.cc b/deps/v8/src/sampler.cc
index c6830e6904..3cb0b749a8 100644
--- a/deps/v8/src/sampler.cc
+++ b/deps/v8/src/sampler.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "sampler.h"
@@ -589,6 +566,7 @@ SamplerThread* SamplerThread::instance_ = NULL;
DISABLE_ASAN void TickSample::Init(Isolate* isolate,
const RegisterState& regs) {
ASSERT(isolate->IsInitialized());
+ timestamp = TimeTicks::HighResolutionNow();
pc = regs.pc;
state = isolate->current_vm_state();
diff --git a/deps/v8/src/sampler.h b/deps/v8/src/sampler.h
index b17a2ed8d5..41da7494dc 100644
--- a/deps/v8/src/sampler.h
+++ b/deps/v8/src/sampler.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_SAMPLER_H_
#define V8_SAMPLER_H_
@@ -69,6 +46,7 @@ struct TickSample {
};
static const int kMaxFramesCount = 64;
Address stack[kMaxFramesCount]; // Call stack.
+ TimeTicks timestamp;
int frames_count : 8; // Number of captured frames.
bool has_external_callback : 1;
StackFrame::Type top_frame_type : 4;
diff --git a/deps/v8/src/scanner-character-streams.cc b/deps/v8/src/scanner-character-streams.cc
index cbef3f95bb..8fbfe4ee96 100644
--- a/deps/v8/src/scanner-character-streams.cc
+++ b/deps/v8/src/scanner-character-streams.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -126,8 +103,6 @@ GenericStringUtf16CharacterStream::GenericStringUtf16CharacterStream(
: string_(data),
length_(end_position) {
ASSERT(end_position >= start_position);
- buffer_cursor_ = buffer_;
- buffer_end_ = buffer_;
pos_ = start_position;
}
diff --git a/deps/v8/src/scanner-character-streams.h b/deps/v8/src/scanner-character-streams.h
index 319ee8fc1c..0d02f02019 100644
--- a/deps/v8/src/scanner-character-streams.h
+++ b/deps/v8/src/scanner-character-streams.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_SCANNER_CHARACTER_STREAMS_H_
#define V8_SCANNER_CHARACTER_STREAMS_H_
@@ -72,7 +49,6 @@ class GenericStringUtf16CharacterStream: public BufferedUtf16CharacterStream {
virtual unsigned FillBuffer(unsigned position, unsigned length);
Handle<String> string_;
- unsigned start_position_;
unsigned length_;
};
diff --git a/deps/v8/src/scanner.cc b/deps/v8/src/scanner.cc
index 48bfd33269..2e039ca403 100644
--- a/deps/v8/src/scanner.cc
+++ b/deps/v8/src/scanner.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Features shared by parsing and pre-parsing scanners.
@@ -1120,10 +1097,10 @@ Handle<String> Scanner::AllocateNextLiteralString(Isolate* isolate,
PretenureFlag tenured) {
if (is_next_literal_one_byte()) {
return isolate->factory()->NewStringFromOneByte(
- Vector<const uint8_t>::cast(next_literal_one_byte_string()), tenured);
+ next_literal_one_byte_string(), tenured).ToHandleChecked();
} else {
return isolate->factory()->NewStringFromTwoByte(
- next_literal_two_byte_string(), tenured);
+ next_literal_two_byte_string(), tenured).ToHandleChecked();
}
}
@@ -1142,7 +1119,8 @@ Handle<String> Scanner::AllocateInternalizedString(Isolate* isolate) {
double Scanner::DoubleValue() {
ASSERT(is_literal_one_byte());
return StringToDouble(
- unicode_cache_, Vector<const char>::cast(literal_one_byte_string()),
+ unicode_cache_,
+ literal_one_byte_string(),
ALLOW_HEX | ALLOW_OCTAL | ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY);
}
@@ -1160,15 +1138,6 @@ int Scanner::FindSymbol(DuplicateFinder* finder, int value) {
}
-void Scanner::LogSymbol(ParserRecorder* log, int position) {
- if (is_literal_one_byte()) {
- log->LogOneByteSymbol(position, literal_one_byte_string());
- } else {
- log->LogTwoByteSymbol(position, literal_two_byte_string());
- }
-}
-
-
int DuplicateFinder::AddOneByteSymbol(Vector<const uint8_t> key, int value) {
return AddSymbol(key, true, value);
}
@@ -1201,7 +1170,7 @@ int DuplicateFinder::AddNumber(Vector<const uint8_t> key, int value) {
int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY;
double double_value = StringToDouble(
- unicode_constants_, Vector<const char>::cast(key), flags, 0.0);
+ unicode_constants_, key, flags, 0.0);
int length;
const char* string;
if (!std::isfinite(double_value)) {
diff --git a/deps/v8/src/scanner.h b/deps/v8/src/scanner.h
index 73026ab5a8..037da5b173 100644
--- a/deps/v8/src/scanner.h
+++ b/deps/v8/src/scanner.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Features shared by parsing and pre-parsing scanners.
@@ -428,8 +405,6 @@ class Scanner {
int FindNumber(DuplicateFinder* finder, int value);
int FindSymbol(DuplicateFinder* finder, int value);
- void LogSymbol(ParserRecorder* log, int position);
-
UnicodeCache* unicode_cache() { return unicode_cache_; }
// Returns the location of the last seen octal literal.
diff --git a/deps/v8/src/scopeinfo.cc b/deps/v8/src/scopeinfo.cc
index e2ae85432a..1ed7e0b777 100644
--- a/deps/v8/src/scopeinfo.cc
+++ b/deps/v8/src/scopeinfo.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <stdlib.h>
@@ -278,6 +255,17 @@ InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
}
+bool ScopeInfo::LocalIsSynthetic(int var) {
+ ASSERT(0 <= var && var < LocalCount());
+ // There's currently no flag stored on the ScopeInfo to indicate that a
+ // variable is a compiler-introduced temporary. However, to avoid conflict
+ // with user declarations, the current temporaries like .generator_object and
+ // .result start with a dot, so we can use that as a flag. It's a hack!
+ Handle<String> name(LocalName(var));
+ return name->length() > 0 && name->Get(0) == '.';
+}
+
+
int ScopeInfo::StackSlotIndex(String* name) {
ASSERT(name->IsInternalizedString());
if (length() > 0) {
@@ -293,35 +281,40 @@ int ScopeInfo::StackSlotIndex(String* name) {
}
-int ScopeInfo::ContextSlotIndex(String* name,
+int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
+ Handle<String> name,
VariableMode* mode,
InitializationFlag* init_flag) {
ASSERT(name->IsInternalizedString());
ASSERT(mode != NULL);
ASSERT(init_flag != NULL);
- if (length() > 0) {
- ContextSlotCache* context_slot_cache = GetIsolate()->context_slot_cache();
- int result = context_slot_cache->Lookup(this, name, mode, init_flag);
+ if (scope_info->length() > 0) {
+ ContextSlotCache* context_slot_cache =
+ scope_info->GetIsolate()->context_slot_cache();
+ int result =
+ context_slot_cache->Lookup(*scope_info, *name, mode, init_flag);
if (result != ContextSlotCache::kNotFound) {
- ASSERT(result < ContextLength());
+ ASSERT(result < scope_info->ContextLength());
return result;
}
- int start = ContextLocalNameEntriesIndex();
- int end = ContextLocalNameEntriesIndex() + ContextLocalCount();
+ int start = scope_info->ContextLocalNameEntriesIndex();
+ int end = scope_info->ContextLocalNameEntriesIndex() +
+ scope_info->ContextLocalCount();
for (int i = start; i < end; ++i) {
- if (name == get(i)) {
+ if (*name == scope_info->get(i)) {
int var = i - start;
- *mode = ContextLocalMode(var);
- *init_flag = ContextLocalInitFlag(var);
+ *mode = scope_info->ContextLocalMode(var);
+ *init_flag = scope_info->ContextLocalInitFlag(var);
result = Context::MIN_CONTEXT_SLOTS + var;
- context_slot_cache->Update(this, name, *mode, *init_flag, result);
- ASSERT(result < ContextLength());
+ context_slot_cache->Update(scope_info, name, *mode, *init_flag, result);
+ ASSERT(result < scope_info->ContextLength());
return result;
}
}
// Cache as not found. Mode and init flag don't matter.
- context_slot_cache->Update(this, name, INTERNAL, kNeedsInitialization, -1);
+ context_slot_cache->Update(
+ scope_info, name, INTERNAL, kNeedsInitialization, -1);
}
return -1;
}
@@ -368,18 +361,21 @@ bool ScopeInfo::CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
int local_count = scope_info->ContextLocalCount();
if (local_count == 0) return true;
// Fill all context locals to the context extension.
+ int first_context_var = scope_info->StackLocalCount();
int start = scope_info->ContextLocalNameEntriesIndex();
- int end = start + local_count;
- for (int i = start; i < end; ++i) {
- int context_index = Context::MIN_CONTEXT_SLOTS + i - start;
- Handle<Object> result = Runtime::SetObjectProperty(
+ for (int i = 0; i < local_count; ++i) {
+ if (scope_info->LocalIsSynthetic(first_context_var + i)) continue;
+ int context_index = Context::MIN_CONTEXT_SLOTS + i;
+ RETURN_ON_EXCEPTION_VALUE(
isolate,
- scope_object,
- Handle<String>(String::cast(scope_info->get(i))),
- Handle<Object>(context->get(context_index), isolate),
- ::NONE,
- SLOPPY);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, false);
+ Runtime::SetObjectProperty(
+ isolate,
+ scope_object,
+ Handle<String>(String::cast(scope_info->get(i + start))),
+ Handle<Object>(context->get(context_index), isolate),
+ ::NONE,
+ SLOPPY),
+ false);
}
return true;
}
@@ -435,19 +431,20 @@ int ContextSlotCache::Lookup(Object* data,
}
-void ContextSlotCache::Update(Object* data,
- String* name,
+void ContextSlotCache::Update(Handle<Object> data,
+ Handle<String> name,
VariableMode mode,
InitializationFlag init_flag,
int slot_index) {
- String* internalized_name;
+ DisallowHeapAllocation no_gc;
+ Handle<String> internalized_name;
ASSERT(slot_index > kNotFound);
- if (name->GetIsolate()->heap()->InternalizeStringIfExists(
- name, &internalized_name)) {
- int index = Hash(data, internalized_name);
+ if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name).
+ ToHandle(&internalized_name)) {
+ int index = Hash(*data, *internalized_name);
Key& key = keys_[index];
- key.data = data;
- key.name = internalized_name;
+ key.data = *data;
+ key.name = *internalized_name;
// Please note value only takes a uint as index.
values_[index] = Value(mode, init_flag, slot_index - kNotFound).raw();
#ifdef DEBUG
@@ -464,18 +461,19 @@ void ContextSlotCache::Clear() {
#ifdef DEBUG
-void ContextSlotCache::ValidateEntry(Object* data,
- String* name,
+void ContextSlotCache::ValidateEntry(Handle<Object> data,
+ Handle<String> name,
VariableMode mode,
InitializationFlag init_flag,
int slot_index) {
- String* internalized_name;
- if (name->GetIsolate()->heap()->InternalizeStringIfExists(
- name, &internalized_name)) {
- int index = Hash(data, name);
+ DisallowHeapAllocation no_gc;
+ Handle<String> internalized_name;
+ if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name).
+ ToHandle(&internalized_name)) {
+ int index = Hash(*data, *name);
Key& key = keys_[index];
- ASSERT(key.data == data);
- ASSERT(key.name->Equals(name));
+ ASSERT(key.data == *data);
+ ASSERT(key.name->Equals(*name));
Value result(values_[index]);
ASSERT(result.mode() == mode);
ASSERT(result.initialization_flag() == init_flag);
diff --git a/deps/v8/src/scopeinfo.h b/deps/v8/src/scopeinfo.h
index a884b3b9ed..755b6a3101 100644
--- a/deps/v8/src/scopeinfo.h
+++ b/deps/v8/src/scopeinfo.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_SCOPEINFO_H_
#define V8_SCOPEINFO_H_
@@ -49,8 +26,8 @@ class ContextSlotCache {
InitializationFlag* init_flag);
// Update an element in the cache.
- void Update(Object* data,
- String* name,
+ void Update(Handle<Object> data,
+ Handle<String> name,
VariableMode mode,
InitializationFlag init_flag,
int slot_index);
@@ -72,8 +49,8 @@ class ContextSlotCache {
inline static int Hash(Object* data, String* name);
#ifdef DEBUG
- void ValidateEntry(Object* data,
- String* name,
+ void ValidateEntry(Handle<Object> data,
+ Handle<String> name,
VariableMode mode,
InitializationFlag init_flag,
int slot_index);
diff --git a/deps/v8/src/scopes.cc b/deps/v8/src/scopes.cc
index bcb6435011..1818909afc 100644
--- a/deps/v8/src/scopes.cc
+++ b/deps/v8/src/scopes.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -402,7 +379,7 @@ Variable* Scope::LocalLookup(Handle<String> name) {
VariableMode mode;
Variable::Location location = Variable::CONTEXT;
InitializationFlag init_flag;
- int index = scope_info_->ContextSlotIndex(*name, &mode, &init_flag);
+ int index = ScopeInfo::ContextSlotIndex(scope_info_, name, &mode, &init_flag);
if (index < 0) {
// Check parameters.
index = scope_info_->ParameterIndex(*name);
@@ -1114,7 +1091,7 @@ bool Scope::ResolveVariable(CompilationInfo* info,
Isolate* isolate = info->isolate();
Factory* factory = isolate->factory();
Handle<JSArray> array = factory->NewJSArray(1);
- USE(JSObject::SetElement(array, 0, var->name(), NONE, STRICT));
+ JSObject::SetElement(array, 0, var->name(), NONE, STRICT).Assert();
Handle<Object> result =
factory->NewSyntaxError("module_type_error", array);
isolate->Throw(*result, &location);
@@ -1266,7 +1243,7 @@ void Scope::AllocateParameterLocals() {
for (int i = params_.length() - 1; i >= 0; --i) {
Variable* var = params_[i];
ASSERT(var->scope() == this);
- if (uses_sloppy_arguments) {
+ if (uses_sloppy_arguments || has_forced_context_allocation()) {
// Force context allocation of the parameter.
var->ForceContextAllocation();
}
diff --git a/deps/v8/src/scopes.h b/deps/v8/src/scopes.h
index b0d84343e4..23a10f19c8 100644
--- a/deps/v8/src/scopes.h
+++ b/deps/v8/src/scopes.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_SCOPES_H_
#define V8_SCOPES_H_
diff --git a/deps/v8/src/serialize.cc b/deps/v8/src/serialize.cc
index 4048886fdb..2b43c0ee69 100644
--- a/deps/v8/src/serialize.cc
+++ b/deps/v8/src/serialize.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -208,25 +185,15 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) {
isolate);
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
// Debug addresses
Add(Debug_Address(Debug::k_after_break_target_address).address(isolate),
DEBUG_ADDRESS,
Debug::k_after_break_target_address << kDebugIdShift,
"Debug::after_break_target_address()");
- Add(Debug_Address(Debug::k_debug_break_slot_address).address(isolate),
- DEBUG_ADDRESS,
- Debug::k_debug_break_slot_address << kDebugIdShift,
- "Debug::debug_break_slot_address()");
- Add(Debug_Address(Debug::k_debug_break_return_address).address(isolate),
- DEBUG_ADDRESS,
- Debug::k_debug_break_return_address << kDebugIdShift,
- "Debug::debug_break_return_address()");
Add(Debug_Address(Debug::k_restarter_frame_function_pointer).address(isolate),
DEBUG_ADDRESS,
Debug::k_restarter_frame_function_pointer << kDebugIdShift,
"Debug::restarter_frame_function_pointer_address()");
-#endif
// Stat counters
struct StatsRefTableEntry {
@@ -271,14 +238,17 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) {
}
// Accessors
-#define ACCESSOR_DESCRIPTOR_DECLARATION(name) \
- Add((Address)&Accessors::name, \
+#define ACCESSOR_INFO_DECLARATION(name) \
+ Add(FUNCTION_ADDR(&Accessors::name##Getter), \
ACCESSOR, \
- Accessors::k##name, \
- "Accessors::" #name);
-
- ACCESSOR_DESCRIPTOR_LIST(ACCESSOR_DESCRIPTOR_DECLARATION)
-#undef ACCESSOR_DESCRIPTOR_DECLARATION
+ Accessors::k##name##Getter, \
+ "Accessors::" #name "Getter"); \
+ Add(FUNCTION_ADDR(&Accessors::name##Setter), \
+ ACCESSOR, \
+ Accessors::k##name##Setter, \
+ "Accessors::" #name "Setter");
+ ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION)
+#undef ACCESSOR_INFO_DECLARATION
StubCache* stub_cache = isolate->stub_cache();
@@ -309,15 +279,6 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) {
"StubCache::secondary_->map");
// Runtime entries
- Add(ExternalReference::perform_gc_function(isolate).address(),
- RUNTIME_ENTRY,
- 1,
- "Runtime::PerformGC");
- // Runtime entries
- Add(ExternalReference::out_of_memory_function(isolate).address(),
- RUNTIME_ENTRY,
- 2,
- "Runtime::OutOfMemory");
Add(ExternalReference::delete_handle_scope_extensions(isolate).address(),
RUNTIME_ENTRY,
4,
@@ -372,10 +333,6 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) {
UNCLASSIFIED,
11,
"Heap::NewSpaceMask()");
- Add(ExternalReference::heap_always_allocate_scope_depth(isolate).address(),
- UNCLASSIFIED,
- 12,
- "Heap::always_allocate_scope_depth()");
Add(ExternalReference::new_space_allocation_limit_address(isolate).address(),
UNCLASSIFIED,
14,
@@ -384,7 +341,6 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) {
UNCLASSIFIED,
15,
"Heap::NewSpaceAllocationTopAddress()");
-#ifdef ENABLE_DEBUGGER_SUPPORT
Add(ExternalReference::debug_break(isolate).address(),
UNCLASSIFIED,
16,
@@ -393,7 +349,6 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) {
UNCLASSIFIED,
17,
"Debug::step_in_fp_addr()");
-#endif
Add(ExternalReference::mod_two_doubles_operation(isolate).address(),
UNCLASSIFIED,
22,
@@ -560,6 +515,26 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) {
62,
"Code::MarkCodeAsExecuted");
+ Add(ExternalReference::is_profiling_address(isolate).address(),
+ UNCLASSIFIED,
+ 63,
+ "CpuProfiler::is_profiling");
+
+ Add(ExternalReference::scheduled_exception_address(isolate).address(),
+ UNCLASSIFIED,
+ 64,
+ "Isolate::scheduled_exception");
+
+ Add(ExternalReference::invoke_function_callback(isolate).address(),
+ UNCLASSIFIED,
+ 65,
+ "InvokeFunctionCallback");
+
+ Add(ExternalReference::invoke_accessor_getter_callback(isolate).address(),
+ UNCLASSIFIED,
+ 66,
+ "InvokeAccessorGetterCallback");
+
// Add a small set of deopt entry addresses to encoder without generating the
// deopt table code, which isn't possible at deserialization time.
HandleScope scope(isolate);
@@ -575,7 +550,7 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) {
ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate)
- : encodings_(Match),
+ : encodings_(HashMap::PointersMatch),
isolate_(isolate) {
ExternalReferenceTable* external_references =
ExternalReferenceTable::instance(isolate_);
@@ -638,10 +613,7 @@ ExternalReferenceDecoder::~ExternalReferenceDecoder() {
DeleteArray(encodings_);
}
-
-bool Serializer::serialization_enabled_ = false;
-bool Serializer::too_late_to_enable_now_ = false;
-
+AtomicWord Serializer::serialization_state_ = SERIALIZER_STATE_UNINITIALIZED;
class CodeAddressMap: public CodeEventLogger {
public:
@@ -669,7 +641,7 @@ class CodeAddressMap: public CodeEventLogger {
private:
class NameMap {
public:
- NameMap() : impl_(&PointerEquals) {}
+ NameMap() : impl_(HashMap::PointersMatch) {}
~NameMap() {
for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) {
@@ -709,10 +681,6 @@ class CodeAddressMap: public CodeEventLogger {
}
private:
- static bool PointerEquals(void* lhs, void* rhs) {
- return lhs == rhs;
- }
-
static char* CopyName(const char* name, int name_size) {
char* result = NewArray<char>(name_size + 1);
for (int i = 0; i < name_size; ++i) {
@@ -758,22 +726,42 @@ class CodeAddressMap: public CodeEventLogger {
CodeAddressMap* Serializer::code_address_map_ = NULL;
-void Serializer::Enable(Isolate* isolate) {
- if (!serialization_enabled_) {
- ASSERT(!too_late_to_enable_now_);
- }
- if (serialization_enabled_) return;
- serialization_enabled_ = true;
+void Serializer::RequestEnable(Isolate* isolate) {
isolate->InitializeLoggingAndCounters();
code_address_map_ = new CodeAddressMap(isolate);
}
-void Serializer::Disable() {
- if (!serialization_enabled_) return;
- serialization_enabled_ = false;
- delete code_address_map_;
- code_address_map_ = NULL;
+void Serializer::InitializeOncePerProcess() {
+ // InitializeOncePerProcess is called by V8::InitializeOncePerProcess, a
+ // method guaranteed to be called only once in a process lifetime.
+ // serialization_state_ is read by many threads, hence the use of
+ // Atomic primitives. Here, we don't need a barrier or mutex to
+ // write it because V8 initialization is done by one thread, and gates
+ // all reads of serialization_state_.
+ ASSERT(NoBarrier_Load(&serialization_state_) ==
+ SERIALIZER_STATE_UNINITIALIZED);
+ SerializationState state = code_address_map_
+ ? SERIALIZER_STATE_ENABLED
+ : SERIALIZER_STATE_DISABLED;
+ NoBarrier_Store(&serialization_state_, state);
+}
+
+
+void Serializer::TearDown() {
+ // TearDown is called by V8::TearDown() for the default isolate. It's safe
+ // to shut down the serializer by that point. Just to be safe, we restore
+ // serialization_state_ to uninitialized.
+ ASSERT(NoBarrier_Load(&serialization_state_) !=
+ SERIALIZER_STATE_UNINITIALIZED);
+ if (code_address_map_) {
+ ASSERT(NoBarrier_Load(&serialization_state_) ==
+ SERIALIZER_STATE_ENABLED);
+ delete code_address_map_;
+ code_address_map_ = NULL;
+ }
+
+ NoBarrier_Store(&serialization_state_, SERIALIZER_STATE_UNINITIALIZED);
}
@@ -865,7 +853,8 @@ void Deserializer::DeserializePartial(Isolate* isolate, Object** root) {
Deserializer::~Deserializer() {
- ASSERT(source_->AtEOF());
+ // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed.
+ // ASSERT(source_->AtEOF());
if (external_reference_decoder_) {
delete external_reference_decoder_;
external_reference_decoder_ = NULL;
@@ -1349,7 +1338,7 @@ void Serializer::VisitPointers(Object** start, Object** end) {
// deserialized objects.
void SerializerDeserializer::Iterate(Isolate* isolate,
ObjectVisitor* visitor) {
- if (Serializer::enabled()) return;
+ if (Serializer::enabled(isolate)) return;
for (int i = 0; ; i++) {
if (isolate->serialize_partial_snapshot_cache_length() <= i) {
// Extend the array ready to get a value from the visitor when
diff --git a/deps/v8/src/serialize.h b/deps/v8/src/serialize.h
index 2947144750..958f20e24f 100644
--- a/deps/v8/src/serialize.h
+++ b/deps/v8/src/serialize.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_SERIALIZE_H_
#define V8_SERIALIZE_H_
@@ -124,8 +101,6 @@ class ExternalReferenceEncoder {
int IndexOf(Address key) const;
- static bool Match(void* key1, void* key2) { return key1 == key2; }
-
void Put(Address key, int index);
Isolate* isolate_;
@@ -414,7 +389,7 @@ class SerializationAddressMapper {
public:
SerializationAddressMapper()
: no_allocation_(),
- serialization_map_(new HashMap(&SerializationMatchFun)) { }
+ serialization_map_(new HashMap(HashMap::PointersMatch)) { }
~SerializationAddressMapper() {
delete serialization_map_;
@@ -438,10 +413,6 @@ class SerializationAddressMapper {
}
private:
- static bool SerializationMatchFun(void* key1, void* key2) {
- return key1 == key2;
- }
-
static uint32_t Hash(HeapObject* obj) {
return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address()));
}
@@ -470,19 +441,22 @@ class Serializer : public SerializerDeserializer {
void VisitPointers(Object** start, Object** end);
// You can call this after serialization to find out how much space was used
// in each space.
- int CurrentAllocationAddress(int space) {
+ int CurrentAllocationAddress(int space) const {
ASSERT(space < kNumberOfSpaces);
return fullness_[space];
}
Isolate* isolate() const { return isolate_; }
- static void Enable(Isolate* isolate);
- static void Disable();
-
- // Call this when you have made use of the fact that there is no serialization
- // going on.
- static void TooLateToEnableNow() { too_late_to_enable_now_ = true; }
- static bool enabled() { return serialization_enabled_; }
+ static void RequestEnable(Isolate* isolate);
+ static void InitializeOncePerProcess();
+ static void TearDown();
+
+ static bool enabled(Isolate* isolate) {
+ SerializationState state = static_cast<SerializationState>(
+ NoBarrier_Load(&serialization_state_));
+ ASSERT(state != SERIALIZER_STATE_UNINITIALIZED);
+ return state == SERIALIZER_STATE_ENABLED;
+ }
SerializationAddressMapper* address_mapper() { return &address_mapper_; }
void PutRoot(int index,
HeapObject* object,
@@ -580,9 +554,15 @@ class Serializer : public SerializerDeserializer {
int fullness_[LAST_SPACE + 1];
SnapshotByteSink* sink_;
ExternalReferenceEncoder* external_reference_encoder_;
- static bool serialization_enabled_;
- // Did we already make use of the fact that serialization was not enabled?
- static bool too_late_to_enable_now_;
+
+ enum SerializationState {
+ SERIALIZER_STATE_UNINITIALIZED = 0,
+ SERIALIZER_STATE_DISABLED = 1,
+ SERIALIZER_STATE_ENABLED = 2
+ };
+
+ static AtomicWord serialization_state_;
+
SerializationAddressMapper address_mapper_;
intptr_t root_index_wave_front_;
void Pad();
diff --git a/deps/v8/src/simulator.h b/deps/v8/src/simulator.h
index b61eaa2609..910e1674ca 100644
--- a/deps/v8/src/simulator.h
+++ b/deps/v8/src/simulator.h
@@ -1,29 +1,6 @@
// Copyright 2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_SIMULATOR_H_
#define V8_SIMULATOR_H_
diff --git a/deps/v8/src/small-pointer-list.h b/deps/v8/src/small-pointer-list.h
index 295a06f26a..2359a8b9fc 100644
--- a/deps/v8/src/small-pointer-list.h
+++ b/deps/v8/src/small-pointer-list.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_SMALL_POINTER_LIST_H_
#define V8_SMALL_POINTER_LIST_H_
diff --git a/deps/v8/src/smart-pointers.h b/deps/v8/src/smart-pointers.h
index 7203c16ba9..db2206a32f 100644
--- a/deps/v8/src/smart-pointers.h
+++ b/deps/v8/src/smart-pointers.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_SMART_POINTERS_H_
#define V8_SMART_POINTERS_H_
diff --git a/deps/v8/src/snapshot-common.cc b/deps/v8/src/snapshot-common.cc
index 4bdf63cedd..b22f2902d3 100644
--- a/deps/v8/src/snapshot-common.cc
+++ b/deps/v8/src/snapshot-common.cc
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// The common functionality when building with or without snapshots.
diff --git a/deps/v8/src/snapshot-empty.cc b/deps/v8/src/snapshot-empty.cc
index 54236d82ec..62b77fe35f 100644
--- a/deps/v8/src/snapshot-empty.cc
+++ b/deps/v8/src/snapshot-empty.cc
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Used for building without snapshots.
diff --git a/deps/v8/src/snapshot.h b/deps/v8/src/snapshot.h
index 4041f2925e..d5271b2dac 100644
--- a/deps/v8/src/snapshot.h
+++ b/deps/v8/src/snapshot.h
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "isolate.h"
diff --git a/deps/v8/src/spaces-inl.h b/deps/v8/src/spaces-inl.h
index 778cb18d72..da9c03d913 100644
--- a/deps/v8/src/spaces-inl.h
+++ b/deps/v8/src/spaces-inl.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_SPACES_INL_H_
#define V8_SPACES_INL_H_
@@ -274,7 +251,7 @@ HeapObject* PagedSpace::AllocateLinearly(int size_in_bytes) {
// Raw allocation.
-MaybeObject* PagedSpace::AllocateRaw(int size_in_bytes) {
+AllocationResult PagedSpace::AllocateRaw(int size_in_bytes) {
HeapObject* object = AllocateLinearly(size_in_bytes);
if (object != NULL) {
if (identity() == CODE_SPACE) {
@@ -303,7 +280,7 @@ MaybeObject* PagedSpace::AllocateRaw(int size_in_bytes) {
return object;
}
- return Failure::RetryAfterGC(identity());
+ return AllocationResult::Retry(identity());
}
@@ -311,7 +288,7 @@ MaybeObject* PagedSpace::AllocateRaw(int size_in_bytes) {
// NewSpace
-MaybeObject* NewSpace::AllocateRaw(int size_in_bytes) {
+AllocationResult NewSpace::AllocateRaw(int size_in_bytes) {
Address old_top = allocation_info_.top();
#ifdef DEBUG
// If we are stressing compaction we waste some memory in new space
diff --git a/deps/v8/src/spaces.cc b/deps/v8/src/spaces.cc
index 6c03daa75a..8e923af548 100644
--- a/deps/v8/src/spaces.cc
+++ b/deps/v8/src/spaces.cc
@@ -1,32 +1,10 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
+#include "full-codegen.h"
#include "macro-assembler.h"
#include "mark-compact.h"
#include "msan.h"
@@ -133,9 +111,19 @@ CodeRange::CodeRange(Isolate* isolate)
}
-bool CodeRange::SetUp(const size_t requested) {
+bool CodeRange::SetUp(size_t requested) {
ASSERT(code_range_ == NULL);
+ if (requested == 0) {
+ // On 64-bit platform(s), we put all code objects in a 512 MB range of
+ // virtual address space, so that they can call each other with near calls.
+ if (kIs64BitArch) {
+ requested = 512 * MB;
+ } else {
+ return true;
+ }
+ }
+
code_range_ = new VirtualMemory(requested);
CHECK(code_range_ != NULL);
if (!code_range_->IsReserved()) {
@@ -146,7 +134,8 @@ bool CodeRange::SetUp(const size_t requested) {
// We are sure that we have mapped a block of requested addresses.
ASSERT(code_range_->size() == requested);
- LOG(isolate_, NewEvent("CodeRange", code_range_->address(), requested));
+ LOG(isolate_,
+ NewEvent("CodeRange", code_range_->address(), requested));
Address base = reinterpret_cast<Address>(code_range_->address());
Address aligned_base =
RoundUp(reinterpret_cast<Address>(code_range_->address()),
@@ -570,10 +559,6 @@ void MemoryChunk::InsertAfter(MemoryChunk* other) {
void MemoryChunk::Unlink() {
- if (!InNewSpace() && IsFlagSet(SCAN_ON_SCAVENGE)) {
- heap_->decrement_scan_on_scavenge_pages();
- ClearFlag(SCAN_ON_SCAVENGE);
- }
MemoryChunk* next_element = next_chunk();
MemoryChunk* prev_element = prev_chunk();
next_element->set_prev_chunk(prev_element);
@@ -711,7 +696,7 @@ MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t reserve_area_size,
executable,
owner);
result->set_reserved_memory(&reservation);
- MSAN_MEMORY_IS_INITIALIZED(base, chunk_size);
+ MSAN_MEMORY_IS_INITIALIZED_IN_JIT(base, chunk_size);
return result;
}
@@ -941,8 +926,8 @@ PagedSpace::PagedSpace(Heap* heap,
: Space(heap, id, executable),
free_list_(this),
was_swept_conservatively_(false),
- first_unswept_page_(Page::FromAddress(NULL)),
- unswept_free_bytes_(0) {
+ unswept_free_bytes_(0),
+ end_of_unswept_pages_(NULL) {
if (id == CODE_SPACE) {
area_size_ = heap->isolate()->memory_allocator()->
CodePageAreaSize();
@@ -993,11 +978,11 @@ size_t PagedSpace::CommittedPhysicalMemory() {
}
-MaybeObject* PagedSpace::FindObject(Address addr) {
+Object* PagedSpace::FindObject(Address addr) {
// Note: this function can only be called on precisely swept spaces.
ASSERT(!heap()->mark_compact_collector()->in_use());
- if (!Contains(addr)) return Failure::Exception();
+ if (!Contains(addr)) return Smi::FromInt(0); // Signaling not found.
Page* p = Page::FromAddress(addr);
HeapObjectIterator it(p, NULL);
@@ -1008,7 +993,7 @@ MaybeObject* PagedSpace::FindObject(Address addr) {
}
UNREACHABLE();
- return Failure::Exception();
+ return Smi::FromInt(0);
}
@@ -1051,7 +1036,7 @@ intptr_t PagedSpace::SizeOfFirstPage() {
int size = 0;
switch (identity()) {
case OLD_POINTER_SPACE:
- size = 72 * kPointerSize * KB;
+ size = 96 * kPointerSize * KB;
break;
case OLD_DATA_SPACE:
size = 192 * KB;
@@ -1072,7 +1057,9 @@ intptr_t PagedSpace::SizeOfFirstPage() {
// upgraded to handle small pages.
size = AreaSize();
} else {
- size = 480 * KB;
+ size = RoundUp(
+ 480 * KB * FullCodeGenerator::kBootCodeSizeMultiplier / 100,
+ kPointerSize);
}
break;
default:
@@ -1115,18 +1102,10 @@ void PagedSpace::IncreaseCapacity(int size) {
}
-void PagedSpace::ReleasePage(Page* page, bool unlink) {
+void PagedSpace::ReleasePage(Page* page) {
ASSERT(page->LiveBytes() == 0);
ASSERT(AreaSize() == page->area_size());
- // Adjust list of unswept pages if the page is the head of the list.
- if (first_unswept_page_ == page) {
- first_unswept_page_ = page->next_page();
- if (first_unswept_page_ == anchor()) {
- first_unswept_page_ = Page::FromAddress(NULL);
- }
- }
-
if (page->WasSwept()) {
intptr_t size = free_list_.EvictFreeListItems(page);
accounting_stats_.AllocateBytes(size);
@@ -1135,19 +1114,19 @@ void PagedSpace::ReleasePage(Page* page, bool unlink) {
DecreaseUnsweptFreeBytes(page);
}
- // TODO(hpayer): This check is just used for debugging purpose and
- // should be removed or turned into an assert after investigating the
- // crash in concurrent sweeping.
- CHECK(!free_list_.ContainsPageFreeListItems(page));
+ if (page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)) {
+ heap()->decrement_scan_on_scavenge_pages();
+ page->ClearFlag(MemoryChunk::SCAN_ON_SCAVENGE);
+ }
+
+ ASSERT(!free_list_.ContainsPageFreeListItems(page));
if (Page::FromAllocationTop(allocation_info_.top()) == page) {
allocation_info_.set_top(NULL);
allocation_info_.set_limit(NULL);
}
- if (unlink) {
- page->Unlink();
- }
+ page->Unlink();
if (page->IsFlagSet(MemoryChunk::CONTAINS_ONLY_DATA)) {
heap()->isolate()->memory_allocator()->Free(page);
} else {
@@ -1195,7 +1174,7 @@ void PagedSpace::Verify(ObjectVisitor* visitor) {
VerifyObject(object);
// The object itself should look OK.
- object->Verify();
+ object->ObjectVerify();
// All the interior pointers should be contained in the heap.
int size = object->Size();
@@ -1420,7 +1399,7 @@ bool NewSpace::AddFreshPage() {
}
-MaybeObject* NewSpace::SlowAllocateRaw(int size_in_bytes) {
+AllocationResult NewSpace::SlowAllocateRaw(int size_in_bytes) {
Address old_top = allocation_info_.top();
Address high = to_space_.page_high();
if (allocation_info_.limit() < high) {
@@ -1442,7 +1421,7 @@ MaybeObject* NewSpace::SlowAllocateRaw(int size_in_bytes) {
top_on_previous_step_ = to_space_.page_low();
return AllocateRaw(size_in_bytes);
} else {
- return Failure::RetryAfterGC();
+ return AllocationResult::Retry();
}
}
@@ -1478,7 +1457,7 @@ void NewSpace::Verify() {
CHECK(!object->IsCode());
// The object itself should look OK.
- object->Verify();
+ object->ObjectVerify();
// All the interior pointers should be contained in the heap.
VerifyPointersVisitor visitor;
@@ -2017,10 +1996,13 @@ void FreeListNode::set_size(Heap* heap, int size_in_bytes) {
// field and a next pointer, we give it a filler map that gives it the
// correct size.
if (size_in_bytes > FreeSpace::kHeaderSize) {
- set_map_no_write_barrier(heap->raw_unchecked_free_space_map());
// Can't use FreeSpace::cast because it fails during deserialization.
+ // We have to set the size first with a release store before we store
+ // the map because a concurrent store buffer scan on scavenge must not
+ // observe a map with an invalid size.
FreeSpace* this_as_free_space = reinterpret_cast<FreeSpace*>(this);
- this_as_free_space->set_size(size_in_bytes);
+ this_as_free_space->nobarrier_set_size(size_in_bytes);
+ synchronized_set_map_no_write_barrier(heap->raw_unchecked_free_space_map());
} else if (size_in_bytes == kPointerSize) {
set_map_no_write_barrier(heap->raw_unchecked_one_pointer_filler_map());
} else if (size_in_bytes == 2 * kPointerSize) {
@@ -2064,11 +2046,11 @@ void FreeListNode::set_next(FreeListNode* next) {
// stage.
if (map() == GetHeap()->raw_unchecked_free_space_map()) {
ASSERT(map() == NULL || Size() >= kNextOffset + kPointerSize);
- Memory::Address_at(address() + kNextOffset) =
- reinterpret_cast<Address>(next);
+ NoBarrier_Store(reinterpret_cast<AtomicWord*>(address() + kNextOffset),
+ reinterpret_cast<AtomicWord>(next));
} else {
- Memory::Address_at(address() + kPointerSize) =
- reinterpret_cast<Address>(next);
+ NoBarrier_Store(reinterpret_cast<AtomicWord*>(address() + kPointerSize),
+ reinterpret_cast<AtomicWord>(next));
}
}
@@ -2488,7 +2470,7 @@ intptr_t FreeListCategory::SumFreeList() {
while (cur != NULL) {
ASSERT(cur->map() == cur->GetHeap()->raw_unchecked_free_space_map());
FreeSpace* cur_as_free_space = reinterpret_cast<FreeSpace*>(cur);
- sum += cur_as_free_space->Size();
+ sum += cur_as_free_space->nobarrier_size();
cur = cur->next();
}
return sum;
@@ -2540,24 +2522,8 @@ void PagedSpace::PrepareForMarkCompact() {
// on the first allocation after the sweep.
EmptyAllocationInfo();
- // Stop lazy sweeping and clear marking bits for unswept pages.
- if (first_unswept_page_ != NULL) {
- Page* p = first_unswept_page_;
- do {
- // Do not use ShouldBeSweptLazily predicate here.
- // New evacuation candidates were selected but they still have
- // to be swept before collection starts.
- if (!p->WasSwept()) {
- Bitmap::Clear(p);
- if (FLAG_gc_verbose) {
- PrintF("Sweeping 0x%" V8PRIxPTR " lazily abandoned.\n",
- reinterpret_cast<intptr_t>(p));
- }
- }
- p = p->next_page();
- } while (p != anchor());
- }
- first_unswept_page_ = Page::FromAddress(NULL);
+ // This counter will be increased for pages which will be swept by the
+ // sweeper threads.
unswept_free_bytes_ = 0;
// Clear the free list before a full GC---it will be rebuilt afterward.
@@ -2566,7 +2532,8 @@ void PagedSpace::PrepareForMarkCompact() {
intptr_t PagedSpace::SizeOfObjects() {
- ASSERT(!heap()->IsSweepingComplete() || (unswept_free_bytes_ == 0));
+ ASSERT(heap()->mark_compact_collector()->IsConcurrentSweepingInProgress() ||
+ (unswept_free_bytes_ == 0));
return Size() - unswept_free_bytes_ - (limit() - top());
}
@@ -2580,39 +2547,6 @@ void PagedSpace::RepairFreeListsAfterBoot() {
}
-bool PagedSpace::AdvanceSweeper(intptr_t bytes_to_sweep) {
- if (IsLazySweepingComplete()) return true;
-
- intptr_t freed_bytes = 0;
- Page* p = first_unswept_page_;
- do {
- Page* next_page = p->next_page();
- if (ShouldBeSweptLazily(p)) {
- if (FLAG_gc_verbose) {
- PrintF("Sweeping 0x%" V8PRIxPTR " lazily advanced.\n",
- reinterpret_cast<intptr_t>(p));
- }
- DecreaseUnsweptFreeBytes(p);
- freed_bytes +=
- MarkCompactCollector::
- SweepConservatively<MarkCompactCollector::SWEEP_SEQUENTIALLY>(
- this, NULL, p);
- }
- p = next_page;
- } while (p != anchor() && freed_bytes < bytes_to_sweep);
-
- if (p == anchor()) {
- first_unswept_page_ = Page::FromAddress(NULL);
- } else {
- first_unswept_page_ = p;
- }
-
- heap()->FreeQueuedChunks();
-
- return IsLazySweepingComplete();
-}
-
-
void PagedSpace::EvictEvacuationCandidatesFromFreeLists() {
if (allocation_info_.top() >= allocation_info_.limit()) return;
@@ -2629,35 +2563,13 @@ void PagedSpace::EvictEvacuationCandidatesFromFreeLists() {
}
-bool PagedSpace::EnsureSweeperProgress(intptr_t size_in_bytes) {
- MarkCompactCollector* collector = heap()->mark_compact_collector();
- if (collector->AreSweeperThreadsActivated()) {
- if (collector->IsConcurrentSweepingInProgress()) {
- if (collector->RefillFreeLists(this) < size_in_bytes) {
- if (!collector->sequential_sweeping()) {
- collector->WaitUntilSweepingCompleted();
- return true;
- }
- }
- return false;
- }
- return true;
- } else {
- return AdvanceSweeper(size_in_bytes);
- }
-}
-
-
HeapObject* PagedSpace::SlowAllocateRaw(int size_in_bytes) {
// Allocation in this space has failed.
- // If there are unswept pages advance lazy sweeper a bounded number of times
- // until we find a size_in_bytes contiguous piece of memory
- const int kMaxSweepingTries = 5;
- bool sweeping_complete = false;
-
- for (int i = 0; i < kMaxSweepingTries && !sweeping_complete; i++) {
- sweeping_complete = EnsureSweeperProgress(size_in_bytes);
+ // If sweeper threads are active, try to re-fill the free-lists.
+ MarkCompactCollector* collector = heap()->mark_compact_collector();
+ if (collector->IsConcurrentSweepingInProgress()) {
+ collector->RefillFreeList(this);
// Retry the free list allocation.
HeapObject* object = free_list_.Allocate(size_in_bytes);
@@ -2678,12 +2590,12 @@ HeapObject* PagedSpace::SlowAllocateRaw(int size_in_bytes) {
return free_list_.Allocate(size_in_bytes);
}
- // Last ditch, sweep all the remaining pages to try to find space. This may
- // cause a pause.
- if (!IsLazySweepingComplete()) {
- EnsureSweeperProgress(kMaxInt);
+ // If sweeper threads are active, wait for them at that point.
+ if (collector->IsConcurrentSweepingInProgress()) {
+ collector->WaitUntilSweepingCompleted();
- // Retry the free list allocation.
+ // After waiting for the sweeper threads, there may be new free-list
+ // entries.
HeapObject* object = free_list_.Allocate(size_in_bytes);
if (object != NULL) return object;
}
@@ -2932,22 +2844,22 @@ void LargeObjectSpace::TearDown() {
}
-MaybeObject* LargeObjectSpace::AllocateRaw(int object_size,
- Executability executable) {
+AllocationResult LargeObjectSpace::AllocateRaw(int object_size,
+ Executability executable) {
// Check if we want to force a GC before growing the old space further.
// If so, fail the allocation.
if (!heap()->always_allocate() &&
heap()->OldGenerationAllocationLimitReached()) {
- return Failure::RetryAfterGC(identity());
+ return AllocationResult::Retry(identity());
}
if (Size() + object_size > max_capacity_) {
- return Failure::RetryAfterGC(identity());
+ return AllocationResult::Retry(identity());
}
LargePage* page = heap()->isolate()->memory_allocator()->
AllocateLargePage(object_size, this, executable);
- if (page == NULL) return Failure::RetryAfterGC(identity());
+ if (page == NULL) return AllocationResult::Retry(identity());
ASSERT(page->area_size() >= object_size);
size_ += static_cast<int>(page->size());
@@ -3000,12 +2912,12 @@ size_t LargeObjectSpace::CommittedPhysicalMemory() {
// GC support
-MaybeObject* LargeObjectSpace::FindObject(Address a) {
+Object* LargeObjectSpace::FindObject(Address a) {
LargePage* page = FindPage(a);
if (page != NULL) {
return page->GetObject();
}
- return Failure::Exception();
+ return Smi::FromInt(0); // Signaling not found.
}
@@ -3086,7 +2998,7 @@ bool LargeObjectSpace::Contains(HeapObject* object) {
bool owned = (chunk->owner() == this);
- SLOW_ASSERT(!owned || !FindObject(address)->IsFailure());
+ SLOW_ASSERT(!owned || FindObject(address)->IsHeapObject());
return owned;
}
@@ -3119,7 +3031,7 @@ void LargeObjectSpace::Verify() {
object->IsFixedDoubleArray() || object->IsByteArray());
// The object itself should look OK.
- object->Verify();
+ object->ObjectVerify();
// Byte arrays and strings don't have interior pointers.
if (object->IsCode()) {
diff --git a/deps/v8/src/spaces.h b/deps/v8/src/spaces.h
index 908e723827..735f1fbbf2 100644
--- a/deps/v8/src/spaces.h
+++ b/deps/v8/src/spaces.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_SPACES_H_
#define V8_SPACES_H_
@@ -33,7 +10,7 @@
#include "list.h"
#include "log.h"
#include "platform/mutex.h"
-#include "v8utils.h"
+#include "utils.h"
namespace v8 {
namespace internal {
@@ -946,7 +923,7 @@ class CodeRange {
// Reserves a range of virtual memory, but does not commit any of it.
// Can only be called once, at heap initialization time.
// Returns false on failure.
- bool SetUp(const size_t requested_size);
+ bool SetUp(size_t requested_size);
// Frees the range of virtual memory, and frees the data structures used to
// manage it.
@@ -1520,9 +1497,8 @@ class FreeListNode: public HeapObject {
inline void Zap();
- static inline FreeListNode* cast(MaybeObject* maybe) {
- ASSERT(!maybe->IsFailure());
- return reinterpret_cast<FreeListNode*>(maybe);
+ static inline FreeListNode* cast(Object* object) {
+ return reinterpret_cast<FreeListNode*>(object);
}
private:
@@ -1693,6 +1669,47 @@ class FreeList {
};
+class AllocationResult {
+ public:
+ // Implicit constructor from Object*.
+ AllocationResult(Object* object) : object_(object), // NOLINT
+ retry_space_(INVALID_SPACE) { }
+
+ AllocationResult() : object_(NULL),
+ retry_space_(INVALID_SPACE) { }
+
+ static inline AllocationResult Retry(AllocationSpace space = NEW_SPACE) {
+ return AllocationResult(space);
+ }
+
+ inline bool IsRetry() { return retry_space_ != INVALID_SPACE; }
+
+ template <typename T>
+ bool To(T** obj) {
+ if (IsRetry()) return false;
+ *obj = T::cast(object_);
+ return true;
+ }
+
+ Object* ToObjectChecked() {
+ CHECK(!IsRetry());
+ return object_;
+ }
+
+ AllocationSpace RetrySpace() {
+ ASSERT(IsRetry());
+ return retry_space_;
+ }
+
+ private:
+ explicit AllocationResult(AllocationSpace space) : object_(NULL),
+ retry_space_(space) { }
+
+ Object* object_;
+ AllocationSpace retry_space_;
+};
+
+
class PagedSpace : public Space {
public:
// Creates a space with a maximum capacity, and an id.
@@ -1722,10 +1739,10 @@ class PagedSpace : public Space {
bool Contains(HeapObject* o) { return Contains(o->address()); }
// Given an address occupied by a live object, return that object if it is
- // in this space, or Failure::Exception() if it is not. The implementation
- // iterates over objects in the page containing the address, the cost is
- // linear in the number of objects in the page. It may be slow.
- MUST_USE_RESULT MaybeObject* FindObject(Address addr);
+ // in this space, or a Smi if it is not. The implementation iterates over
+ // objects in the page containing the address, the cost is linear in the
+ // number of objects in the page. It may be slow.
+ Object* FindObject(Address addr);
// During boot the free_space_map is created, and afterwards we may need
// to write it into the free list nodes that were already created.
@@ -1783,8 +1800,9 @@ class PagedSpace : public Space {
intptr_t Available() { return free_list_.available(); }
// Allocated bytes in this space. Garbage bytes that were not found due to
- // lazy sweeping are counted as being allocated! The bytes in the current
- // linear allocation area (between top and limit) are also counted here.
+ // concurrent sweeping are counted as being allocated! The bytes in the
+ // current linear allocation area (between top and limit) are also counted
+ // here.
virtual intptr_t Size() { return accounting_stats_.Size(); }
// As size, but the bytes in lazily swept pages are estimated and the bytes
@@ -1812,7 +1830,7 @@ class PagedSpace : public Space {
// Allocate the requested number of bytes in the space if possible, return a
// failure object if not.
- MUST_USE_RESULT inline MaybeObject* AllocateRaw(int size_in_bytes);
+ MUST_USE_RESULT inline AllocationResult AllocateRaw(int size_in_bytes);
// Give a block of memory to the space's free list. It might be added to
// the free list or accounted as waste.
@@ -1853,7 +1871,7 @@ class PagedSpace : public Space {
void IncreaseCapacity(int size);
// Releases an unused page and shrinks the space.
- void ReleasePage(Page* page, bool unlink);
+ void ReleasePage(Page* page);
// The dummy page that anchors the linked list of pages.
Page* anchor() { return &anchor_; }
@@ -1885,24 +1903,18 @@ class PagedSpace : public Space {
// Evacuation candidates are swept by evacuator. Needs to return a valid
// result before _and_ after evacuation has finished.
- static bool ShouldBeSweptLazily(Page* p) {
+ static bool ShouldBeSweptBySweeperThreads(Page* p) {
return !p->IsEvacuationCandidate() &&
!p->IsFlagSet(Page::RESCAN_ON_EVACUATION) &&
!p->WasSweptPrecisely();
}
- void SetPagesToSweep(Page* first) {
- ASSERT(unswept_free_bytes_ == 0);
- if (first == &anchor_) first = NULL;
- first_unswept_page_ = first;
- }
-
void IncrementUnsweptFreeBytes(intptr_t by) {
unswept_free_bytes_ += by;
}
void IncreaseUnsweptFreeBytes(Page* p) {
- ASSERT(ShouldBeSweptLazily(p));
+ ASSERT(ShouldBeSweptBySweeperThreads(p));
unswept_free_bytes_ += (p->area_size() - p->LiveBytes());
}
@@ -1911,7 +1923,7 @@ class PagedSpace : public Space {
}
void DecreaseUnsweptFreeBytes(Page* p) {
- ASSERT(ShouldBeSweptLazily(p));
+ ASSERT(ShouldBeSweptBySweeperThreads(p));
unswept_free_bytes_ -= (p->area_size() - p->LiveBytes());
}
@@ -1919,15 +1931,18 @@ class PagedSpace : public Space {
unswept_free_bytes_ = 0;
}
- bool AdvanceSweeper(intptr_t bytes_to_sweep);
-
- // When parallel sweeper threads are active and the main thread finished
- // its sweeping phase, this function waits for them to complete, otherwise
- // AdvanceSweeper with size_in_bytes is called.
+ // This function tries to steal size_in_bytes memory from the sweeper threads
+ // free-lists. If it does not succeed stealing enough memory, it will wait
+ // for the sweeper threads to finish sweeping.
+ // It returns true when sweeping is completed and false otherwise.
bool EnsureSweeperProgress(intptr_t size_in_bytes);
- bool IsLazySweepingComplete() {
- return !first_unswept_page_->is_valid();
+ void set_end_of_unswept_pages(Page* page) {
+ end_of_unswept_pages_ = page;
+ }
+
+ Page* end_of_unswept_pages() {
+ return end_of_unswept_pages_;
}
Page* FirstPage() { return anchor_.next_page(); }
@@ -1969,15 +1984,16 @@ class PagedSpace : public Space {
bool was_swept_conservatively_;
- // The first page to be swept when the lazy sweeper advances. Is set
- // to NULL when all pages have been swept.
- Page* first_unswept_page_;
-
// The number of free bytes which could be reclaimed by advancing the
- // lazy sweeper. This is only an estimation because lazy sweeping is
- // done conservatively.
+ // concurrent sweeper threads. This is only an estimation because concurrent
+ // sweeping is done conservatively.
intptr_t unswept_free_bytes_;
+ // The sweeper threads iterate over the list of pointer and data space pages
+ // and sweep these pages concurrently. They will stop sweeping after the
+ // end_of_unswept_pages_ page.
+ Page* end_of_unswept_pages_;
+
// Expands the space by allocating a fixed number of pages. Returns false if
// it cannot allocate requested number of pages from OS, or if the hard heap
// size limit has been hit.
@@ -2540,7 +2556,7 @@ class NewSpace : public Space {
return allocation_info_.limit_address();
}
- MUST_USE_RESULT INLINE(MaybeObject* AllocateRaw(int size_in_bytes));
+ MUST_USE_RESULT INLINE(AllocationResult AllocateRaw(int size_in_bytes));
// Reset the allocation pointer to the beginning of the active semispace.
void ResetAllocationInfo();
@@ -2657,7 +2673,7 @@ class NewSpace : public Space {
HistogramInfo* allocated_histogram_;
HistogramInfo* promoted_histogram_;
- MUST_USE_RESULT MaybeObject* SlowAllocateRaw(int size_in_bytes);
+ MUST_USE_RESULT AllocationResult SlowAllocateRaw(int size_in_bytes);
friend class SemiSpaceIterator;
@@ -2812,8 +2828,8 @@ class LargeObjectSpace : public Space {
// Shared implementation of AllocateRaw, AllocateRawCode and
// AllocateRawFixedArray.
- MUST_USE_RESULT MaybeObject* AllocateRaw(int object_size,
- Executability executable);
+ MUST_USE_RESULT AllocationResult AllocateRaw(int object_size,
+ Executability executable);
// Available bytes for objects in this space.
inline intptr_t Available();
@@ -2841,10 +2857,9 @@ class LargeObjectSpace : public Space {
return page_count_;
}
- // Finds an object for a given address, returns Failure::Exception()
- // if it is not found. The function iterates through all objects in this
- // space, may be slow.
- MaybeObject* FindObject(Address a);
+ // Finds an object for a given address, returns a Smi if it is not found.
+ // The function iterates through all objects in this space, may be slow.
+ Object* FindObject(Address a);
// Finds a large object page containing the given address, returns NULL
// if such a page doesn't exist.
@@ -2872,7 +2887,7 @@ class LargeObjectSpace : public Space {
#endif
// Checks whether an address is in the object area in this space. It
// iterates all objects in the space. May be slow.
- bool SlowContains(Address addr) { return !FindObject(addr)->IsFailure(); }
+ bool SlowContains(Address addr) { return FindObject(addr)->IsHeapObject(); }
private:
intptr_t max_capacity_;
diff --git a/deps/v8/src/splay-tree-inl.h b/deps/v8/src/splay-tree-inl.h
index 42024756e9..fe40f276cd 100644
--- a/deps/v8/src/splay-tree-inl.h
+++ b/deps/v8/src/splay-tree-inl.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_SPLAY_TREE_INL_H_
#define V8_SPLAY_TREE_INL_H_
diff --git a/deps/v8/src/splay-tree.h b/deps/v8/src/splay-tree.h
index f393027a82..77f05b010e 100644
--- a/deps/v8/src/splay-tree.h
+++ b/deps/v8/src/splay-tree.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_SPLAY_TREE_H_
#define V8_SPLAY_TREE_H_
diff --git a/deps/v8/src/store-buffer-inl.h b/deps/v8/src/store-buffer-inl.h
index 7e5432c841..709415e45b 100644
--- a/deps/v8/src/store-buffer-inl.h
+++ b/deps/v8/src/store-buffer-inl.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_STORE_BUFFER_INL_H_
#define V8_STORE_BUFFER_INL_H_
diff --git a/deps/v8/src/store-buffer.cc b/deps/v8/src/store-buffer.cc
index a1479b2b9a..b0f7d2f803 100644
--- a/deps/v8/src/store-buffer.cc
+++ b/deps/v8/src/store-buffer.cc
@@ -1,37 +1,14 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "store-buffer.h"
#include <algorithm>
#include "v8.h"
+#include "counters.h"
#include "store-buffer-inl.h"
-#include "v8-counters.h"
namespace v8 {
namespace internal {
@@ -388,7 +365,9 @@ void StoreBuffer::VerifyPointers(LargeObjectSpace* space) {
// When we are not in GC the Heap::InNewSpace() predicate
// checks that pointers which satisfy predicate point into
// the active semispace.
- heap_->InNewSpace(*slot);
+ Object* object = reinterpret_cast<Object*>(
+ NoBarrier_Load(reinterpret_cast<AtomicWord*>(slot)));
+ heap_->InNewSpace(object);
slot_address += kPointerSize;
}
}
@@ -427,14 +406,18 @@ void StoreBuffer::FindPointersToNewSpaceInRegion(
slot_address < end;
slot_address += kPointerSize) {
Object** slot = reinterpret_cast<Object**>(slot_address);
- if (heap_->InNewSpace(*slot)) {
- HeapObject* object = reinterpret_cast<HeapObject*>(*slot);
- ASSERT(object->IsHeapObject());
+ Object* object = reinterpret_cast<Object*>(
+ NoBarrier_Load(reinterpret_cast<AtomicWord*>(slot)));
+ if (heap_->InNewSpace(object)) {
+ HeapObject* heap_object = reinterpret_cast<HeapObject*>(object);
+ ASSERT(heap_object->IsHeapObject());
// The new space object was not promoted if it still contains a map
// pointer. Clear the map field now lazily.
- if (clear_maps) ClearDeadObject(object);
- slot_callback(reinterpret_cast<HeapObject**>(slot), object);
- if (heap_->InNewSpace(*slot)) {
+ if (clear_maps) ClearDeadObject(heap_object);
+ slot_callback(reinterpret_cast<HeapObject**>(slot), heap_object);
+ object = reinterpret_cast<Object*>(
+ NoBarrier_Load(reinterpret_cast<AtomicWord*>(slot)));
+ if (heap_->InNewSpace(object)) {
EnterDirectlyIntoStoreBuffer(slot_address);
}
}
@@ -502,9 +485,9 @@ void StoreBuffer::FindPointersToNewSpaceInMapsRegion(
// This function iterates over all the pointers in a paged space in the heap,
// looking for pointers into new space. Within the pages there may be dead
// objects that have not been overwritten by free spaces or fillers because of
-// lazy sweeping. These dead objects may not contain pointers to new space.
-// The garbage areas that have been swept properly (these will normally be the
-// large ones) will be marked with free space and filler map words. In
+// concurrent sweeping. These dead objects may not contain pointers to new
+// space. The garbage areas that have been swept properly (these will normally
+// be the large ones) will be marked with free space and filler map words. In
// addition any area that has never been used at all for object allocation must
// be marked with a free space or filler. Because the free space and filler
// maps do not move we can always recognize these even after a compaction.
@@ -531,7 +514,11 @@ void StoreBuffer::FindPointersToNewSpaceOnPage(
Object* constant_pool_array_map = heap_->constant_pool_array_map();
while (visitable_end < end_of_page) {
- Object* o = *reinterpret_cast<Object**>(visitable_end);
+ // The sweeper thread concurrently may write free space maps and size to
+ // this page. We need acquire load here to make sure that we get a
+ // consistent view of maps and their sizes.
+ Object* o = reinterpret_cast<Object*>(
+ Acquire_Load(reinterpret_cast<AtomicWord*>(visitable_end)));
// Skip fillers or constant pool arrays (which never contain new-space
// pointers but can contain pointers which can be confused for fillers)
// but not things that look like fillers in the special garbage section
@@ -595,14 +582,17 @@ void StoreBuffer::IteratePointersInStoreBuffer(
Address* saved_top = old_top_;
#endif
Object** slot = reinterpret_cast<Object**>(*current);
- Object* object = *slot;
+ Object* object = reinterpret_cast<Object*>(
+ NoBarrier_Load(reinterpret_cast<AtomicWord*>(slot)));
if (heap_->InFromSpace(object)) {
HeapObject* heap_object = reinterpret_cast<HeapObject*>(object);
// The new space object was not promoted if it still contains a map
// pointer. Clear the map field now lazily.
if (clear_maps) ClearDeadObject(heap_object);
slot_callback(reinterpret_cast<HeapObject**>(slot), heap_object);
- if (heap_->InNewSpace(*slot)) {
+ object = reinterpret_cast<Object*>(
+ NoBarrier_Load(reinterpret_cast<AtomicWord*>(slot)));
+ if (heap_->InNewSpace(object)) {
EnterDirectlyIntoStoreBuffer(reinterpret_cast<Address>(slot));
}
}
diff --git a/deps/v8/src/store-buffer.h b/deps/v8/src/store-buffer.h
index 01e7cbeb8d..bf3a3f7378 100644
--- a/deps/v8/src/store-buffer.h
+++ b/deps/v8/src/store-buffer.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_STORE_BUFFER_H_
#define V8_STORE_BUFFER_H_
diff --git a/deps/v8/src/string-search.cc b/deps/v8/src/string-search.cc
index 3ae68b5d40..38dacc9cc5 100644
--- a/deps/v8/src/string-search.cc
+++ b/deps/v8/src/string-search.cc
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
#include "string-search.h"
diff --git a/deps/v8/src/string-search.h b/deps/v8/src/string-search.h
index bc685ffe58..09bc36ef82 100644
--- a/deps/v8/src/string-search.h
+++ b/deps/v8/src/string-search.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_STRING_SEARCH_H_
#define V8_STRING_SEARCH_H_
diff --git a/deps/v8/src/string-stream.cc b/deps/v8/src/string-stream.cc
index e2d15f5405..25e340b4a5 100644
--- a/deps/v8/src/string-stream.cc
+++ b/deps/v8/src/string-stream.cc
@@ -1,35 +1,11 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "v8.h"
-
-#include "factory.h"
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
#include "string-stream.h"
+#include "handles-inl.h"
+
namespace v8 {
namespace internal {
@@ -290,7 +266,7 @@ void StringStream::OutputToFile(FILE* out) {
Handle<String> StringStream::ToString(Isolate* isolate) {
return isolate->factory()->NewStringFromUtf8(
- Vector<const char>(buffer_, length_));
+ Vector<const char>(buffer_, length_)).ToHandleChecked();
}
diff --git a/deps/v8/src/string-stream.h b/deps/v8/src/string-stream.h
index e3db2a8a86..ecc0e80f5d 100644
--- a/deps/v8/src/string-stream.h
+++ b/deps/v8/src/string-stream.h
@@ -1,40 +1,18 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_STRING_STREAM_H_
#define V8_STRING_STREAM_H_
+#include "handles.h"
+
namespace v8 {
namespace internal {
-
class StringAllocator {
public:
- virtual ~StringAllocator() {}
+ virtual ~StringAllocator() { }
// Allocate a number of bytes.
virtual char* allocate(unsigned bytes) = 0;
// Allocate a larger number of bytes and copy the old buffer to the new one.
@@ -46,11 +24,12 @@ class StringAllocator {
// Normal allocator uses new[] and delete[].
-class HeapStringAllocator: public StringAllocator {
+class HeapStringAllocator V8_FINAL : public StringAllocator {
public:
~HeapStringAllocator() { DeleteArray(space_); }
- char* allocate(unsigned bytes);
- char* grow(unsigned* bytes);
+ virtual char* allocate(unsigned bytes) V8_OVERRIDE;
+ virtual char* grow(unsigned* bytes) V8_OVERRIDE;
+
private:
char* space_;
};
@@ -59,18 +38,19 @@ class HeapStringAllocator: public StringAllocator {
// Allocator for use when no new c++ heap allocation is allowed.
// Given a preallocated buffer up front and does no allocation while
// building message.
-class NoAllocationStringAllocator: public StringAllocator {
+class NoAllocationStringAllocator V8_FINAL : public StringAllocator {
public:
NoAllocationStringAllocator(char* memory, unsigned size);
- char* allocate(unsigned bytes) { return space_; }
- char* grow(unsigned* bytes);
+ virtual char* allocate(unsigned bytes) V8_OVERRIDE { return space_; }
+ virtual char* grow(unsigned* bytes) V8_OVERRIDE;
+
private:
unsigned size_;
char* space_;
};
-class FmtElm {
+class FmtElm V8_FINAL {
public:
FmtElm(int value) : type_(INT) { // NOLINT
data_.u_int_ = value;
@@ -110,7 +90,7 @@ class FmtElm {
};
-class StringStream {
+class StringStream V8_FINAL {
public:
explicit StringStream(StringAllocator* allocator):
allocator_(allocator),
@@ -120,9 +100,6 @@ class StringStream {
buffer_[0] = 0;
}
- ~StringStream() {
- }
-
bool Put(char c);
bool Put(String* str);
bool Put(String* str, int start, int end);
@@ -175,7 +152,6 @@ class StringStream {
static bool IsMentionedObjectCacheClear(Isolate* isolate);
#endif
-
static const int kInitialCapacity = 16;
private:
@@ -194,7 +170,7 @@ class StringStream {
// Utility class to print a list of items to a stream, divided by a separator.
-class SimpleListPrinter {
+class SimpleListPrinter V8_FINAL {
public:
explicit SimpleListPrinter(StringStream* stream, char separator = ',') {
separator_ = separator;
@@ -217,7 +193,6 @@ class SimpleListPrinter {
StringStream* stream_;
};
-
} } // namespace v8::internal
#endif // V8_STRING_STREAM_H_
diff --git a/deps/v8/src/string.js b/deps/v8/src/string.js
index 74230c9864..9c90427835 100644
--- a/deps/v8/src/string.js
+++ b/deps/v8/src/string.js
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file relies on the fact that the following declaration has been made
// in runtime.js:
@@ -173,7 +150,6 @@ function StringMatch(regexp) {
var lastIndex = regexp.lastIndex;
TO_INTEGER_FOR_SIDE_EFFECT(lastIndex);
if (!regexp.global) return RegExpExecNoTests(regexp, subject, 0);
- %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]);
// lastMatchInfo is defined in regexp.js.
var result = %StringMatch(subject, regexp, lastMatchInfo);
if (result !== null) lastMatchInfoOverride = null;
@@ -244,7 +220,6 @@ function StringReplace(search, replace) {
// value is discarded.
var lastIndex = search.lastIndex;
TO_INTEGER_FOR_SIDE_EFFECT(lastIndex);
- %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]);
if (!IS_SPEC_FUNCTION(replace)) {
replace = TO_STRING_INLINE(replace);
@@ -646,8 +621,6 @@ function StringSplit(separator, limit) {
var ArrayPushBuiltin = $Array.prototype.push;
function StringSplitOnRegExp(subject, separator, limit, length) {
- %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]);
-
if (length === 0) {
if (DoRegExpExec(separator, subject, 0, 0) != null) {
return [];
@@ -658,7 +631,7 @@ function StringSplitOnRegExp(subject, separator, limit, length) {
var currentIndex = 0;
var startIndex = 0;
var startMatch = 0;
- var result = [];
+ var result = new InternalArray();
outer_loop:
while (true) {
@@ -703,7 +676,9 @@ function StringSplitOnRegExp(subject, separator, limit, length) {
startIndex = currentIndex = endIndex;
}
- return result;
+ var array_result = [];
+ %MoveArrayContents(result, array_result);
+ return array_result;
}
diff --git a/deps/v8/src/strtod.cc b/deps/v8/src/strtod.cc
index d332fd2bc4..aac74199ab 100644
--- a/deps/v8/src/strtod.cc
+++ b/deps/v8/src/strtod.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <stdarg.h>
#include <cmath>
diff --git a/deps/v8/src/strtod.h b/deps/v8/src/strtod.h
index 1a5a96c8eb..f4ce731a17 100644
--- a/deps/v8/src/strtod.h
+++ b/deps/v8/src/strtod.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_STRTOD_H_
#define V8_STRTOD_H_
diff --git a/deps/v8/src/stub-cache.cc b/deps/v8/src/stub-cache.cc
index ff641dddf9..6bf209bc0a 100644
--- a/deps/v8/src/stub-cache.cc
+++ b/deps/v8/src/stub-cache.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -335,7 +312,7 @@ Handle<Code> StubCache::ComputeCompareNil(Handle<Map> receiver_map,
Code::FindAndReplacePattern pattern;
pattern.Add(isolate_->factory()->meta_map(), receiver_map);
- Handle<Code> ic = stub.GetCodeCopy(isolate_, pattern);
+ Handle<Code> ic = stub.GetCodeCopy(pattern);
if (!receiver_map->is_shared()) {
Map::UpdateCodeCache(receiver_map, name, ic);
@@ -478,7 +455,7 @@ void StubCache::CollectMatchingMaps(SmallMapList* types,
// StubCompiler implementation.
-RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty) {
+RUNTIME_FUNCTION(StoreCallbackProperty) {
JSObject* receiver = JSObject::cast(args[0]);
JSObject* holder = JSObject::cast(args[1]);
ExecutableAccessorInfo* callback = ExecutableAccessorInfo::cast(args[2]);
@@ -499,7 +476,7 @@ RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty) {
PropertyCallbackArguments
custom_args(isolate, callback->data(), receiver, holder);
custom_args.Call(fun, v8::Utils::ToLocal(str), v8::Utils::ToLocal(value));
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *value;
}
@@ -511,7 +488,7 @@ RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty) {
* Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't
* provide any value for the given name.
*/
-RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) {
+RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly) {
ASSERT(args.length() == StubCache::kInterceptorArgsLength);
Handle<Name> name_handle =
args.at<Name>(StubCache::kInterceptorArgsNameIndex);
@@ -539,7 +516,7 @@ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) {
HandleScope scope(isolate);
v8::Handle<v8::Value> r =
callback_args.Call(getter, v8::Utils::ToLocal(name));
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
if (!r.IsEmpty()) {
Handle<Object> result = v8::Utils::OpenHandle(*r);
result->VerifyApiCallResultType();
@@ -551,7 +528,7 @@ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) {
}
-static MaybeObject* ThrowReferenceError(Isolate* isolate, Name* name) {
+static Object* ThrowReferenceError(Isolate* isolate, Name* name) {
// If the load is non-contextual, just return the undefined result.
// Note that both keyed and non-keyed loads may end up here.
HandleScope scope(isolate);
@@ -569,8 +546,9 @@ static MaybeObject* ThrowReferenceError(Isolate* isolate, Name* name) {
}
-static Handle<Object> LoadWithInterceptor(Arguments* args,
- PropertyAttributes* attrs) {
+MUST_USE_RESULT static MaybeHandle<Object> LoadWithInterceptor(
+ Arguments* args,
+ PropertyAttributes* attrs) {
ASSERT(args->length() == StubCache::kInterceptorArgsLength);
Handle<Name> name_handle =
args->at<Name>(StubCache::kInterceptorArgsNameIndex);
@@ -604,7 +582,7 @@ static Handle<Object> LoadWithInterceptor(Arguments* args,
// Use the interceptor getter.
v8::Handle<v8::Value> r =
callback_args.Call(getter, v8::Utils::ToLocal(name));
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (!r.IsEmpty()) {
*attrs = NONE;
Handle<Object> result = v8::Utils::OpenHandle(*r);
@@ -613,9 +591,8 @@ static Handle<Object> LoadWithInterceptor(Arguments* args,
}
}
- Handle<Object> result = JSObject::GetPropertyPostInterceptor(
+ return JSObject::GetPropertyPostInterceptor(
holder_handle, receiver_handle, name_handle, attrs);
- return result;
}
@@ -623,11 +600,12 @@ static Handle<Object> LoadWithInterceptor(Arguments* args,
* Loads a property with an interceptor performing post interceptor
* lookup if interceptor failed.
*/
-RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad) {
+RUNTIME_FUNCTION(LoadPropertyWithInterceptorForLoad) {
PropertyAttributes attr = NONE;
HandleScope scope(isolate);
- Handle<Object> result = LoadWithInterceptor(&args, &attr);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, LoadWithInterceptor(&args, &attr));
// If the property is present, return it.
if (attr != ABSENT) return *result;
@@ -635,11 +613,12 @@ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad) {
}
-RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) {
+RUNTIME_FUNCTION(LoadPropertyWithInterceptorForCall) {
PropertyAttributes attr;
HandleScope scope(isolate);
- Handle<Object> result = LoadWithInterceptor(&args, &attr);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, LoadWithInterceptor(&args, &attr));
// This is call IC. In this case, we simply return the undefined result which
// will lead to an exception when trying to invoke the result as a
// function.
@@ -647,7 +626,7 @@ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) {
}
-RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) {
+RUNTIME_FUNCTION(StoreInterceptorProperty) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
@@ -656,21 +635,24 @@ RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) {
Handle<Object> value = args.at<Object>(2);
ASSERT(receiver->HasNamedInterceptor());
PropertyAttributes attr = NONE;
- Handle<Object> result = JSObject::SetPropertyWithInterceptor(
- receiver, name, value, attr, ic.strict_mode());
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ JSObject::SetPropertyWithInterceptor(
+ receiver, name, value, attr, ic.strict_mode()));
return *result;
}
-RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) {
+RUNTIME_FUNCTION(KeyedLoadPropertyWithInterceptor) {
HandleScope scope(isolate);
Handle<JSObject> receiver = args.at<JSObject>(0);
ASSERT(args.smi_at(1) >= 0);
uint32_t index = args.smi_at(1);
- Handle<Object> result =
- JSObject::GetElementWithInterceptor(receiver, receiver, index);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ JSObject::GetElementWithInterceptor(receiver, receiver, index));
return *result;
}
@@ -777,10 +759,10 @@ Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder,
Handle<Name> name,
LookupResult* lookup) {
- holder->LocalLookupRealNamedProperty(*name, lookup);
+ holder->LocalLookupRealNamedProperty(name, lookup);
if (lookup->IsFound()) return;
if (holder->GetPrototype()->IsNull()) return;
- holder->GetPrototype()->Lookup(*name, lookup);
+ holder->GetPrototype()->Lookup(name, lookup);
}
@@ -802,9 +784,6 @@ Register LoadStubCompiler::HandlerFrontendHeader(
} else if (type->Is(HeapType::Number())) {
function_index = Context::NUMBER_FUNCTION_INDEX;
} else if (type->Is(HeapType::Boolean())) {
- // Booleans use the generic oddball map, so an additional check is needed to
- // ensure the receiver is really a boolean.
- GenerateBooleanCheck(object_reg, miss);
function_index = Context::BOOLEAN_FUNCTION_INDEX;
} else {
check_type = SKIP_RECEIVER;
@@ -886,7 +865,7 @@ void LoadStubCompiler::NonexistentHandlerFrontend(Handle<HeapType> type,
name = factory()->InternalizeString(Handle<String>::cast(name));
}
ASSERT(last.is_null() ||
- last->property_dictionary()->FindEntry(*name) ==
+ last->property_dictionary()->FindEntry(name) ==
NameDictionary::kNotFound);
GenerateDictionaryNegativeLookup(masm(), &miss, holder, name,
scratch2(), scratch3());
@@ -896,7 +875,7 @@ void LoadStubCompiler::NonexistentHandlerFrontend(Handle<HeapType> type,
// check that the global property cell is empty.
if (last_map->IsJSGlobalObjectMap()) {
Handle<JSGlobalObject> global = last.is_null()
- ? Handle<JSGlobalObject>::cast(type->AsConstant())
+ ? Handle<JSGlobalObject>::cast(type->AsConstant()->Value())
: Handle<JSGlobalObject>::cast(last);
GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
}
@@ -1183,13 +1162,14 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
receiver_map->has_external_array_elements() ||
receiver_map->has_fixed_typed_array_elements()) {
Handle<Code> stub = KeyedLoadFastElementStub(
+ isolate(),
receiver_map->instance_type() == JS_ARRAY_TYPE,
- elements_kind).GetCode(isolate());
+ elements_kind).GetCode();
__ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
} else {
Handle<Code> stub = FLAG_compiled_keyed_dictionary_loads
- ? KeyedLoadDictionaryElementStub().GetCode(isolate())
- : KeyedLoadDictionaryElementPlatformStub().GetCode(isolate());
+ ? KeyedLoadDictionaryElementStub(isolate()).GetCode()
+ : KeyedLoadDictionaryElementPlatformStub(isolate()).GetCode();
__ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
}
@@ -1209,13 +1189,15 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
receiver_map->has_external_array_elements() ||
receiver_map->has_fixed_typed_array_elements()) {
stub = KeyedStoreFastElementStub(
+ isolate(),
is_jsarray,
elements_kind,
- store_mode()).GetCode(isolate());
+ store_mode()).GetCode();
} else {
- stub = KeyedStoreElementStub(is_jsarray,
+ stub = KeyedStoreElementStub(isolate(),
+ is_jsarray,
elements_kind,
- store_mode()).GetCode(isolate());
+ store_mode()).GetCode();
}
__ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
@@ -1272,6 +1254,7 @@ Handle<Code> BaseLoadStoreStubCompiler::GetICCode(Code::Kind kind,
InlineCacheState state) {
Code::Flags flags = Code::ComputeFlags(kind, state, extra_state(), type);
Handle<Code> code = GetCodeWithFlags(flags, name);
+ IC::RegisterWeakMapDependency(code);
PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
JitEvent(name, code);
return code;
@@ -1308,13 +1291,15 @@ void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps,
IsExternalArrayElementsKind(elements_kind) ||
IsFixedTypedArrayElementsKind(elements_kind)) {
cached_stub =
- KeyedLoadFastElementStub(is_js_array,
- elements_kind).GetCode(isolate());
+ KeyedLoadFastElementStub(isolate(),
+ is_js_array,
+ elements_kind).GetCode();
} else if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) {
cached_stub = isolate()->builtins()->KeyedLoadIC_SloppyArguments();
} else {
ASSERT(elements_kind == DICTIONARY_ELEMENTS);
- cached_stub = KeyedLoadDictionaryElementStub().GetCode(isolate());
+ cached_stub =
+ KeyedLoadDictionaryElementStub(isolate()).GetCode();
}
}
@@ -1343,10 +1328,11 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreElementPolymorphic(
ElementsKind elements_kind = receiver_map->elements_kind();
if (!transitioned_map.is_null()) {
cached_stub = ElementsTransitionAndStoreStub(
+ isolate(),
elements_kind,
transitioned_map->elements_kind(),
is_js_array,
- store_mode()).GetCode(isolate());
+ store_mode()).GetCode();
} else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
cached_stub = isolate()->builtins()->KeyedStoreIC_Slow();
} else {
@@ -1354,14 +1340,16 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreElementPolymorphic(
receiver_map->has_external_array_elements() ||
receiver_map->has_fixed_typed_array_elements()) {
cached_stub = KeyedStoreFastElementStub(
+ isolate(),
is_js_array,
elements_kind,
- store_mode()).GetCode(isolate());
+ store_mode()).GetCode();
} else {
cached_stub = KeyedStoreElementStub(
+ isolate(),
is_js_array,
elements_kind,
- store_mode()).GetCode(isolate());
+ store_mode()).GetCode();
}
}
ASSERT(!cached_stub.is_null());
diff --git a/deps/v8/src/stub-cache.h b/deps/v8/src/stub-cache.h
index 7a304fe71a..707df6c7bb 100644
--- a/deps/v8/src/stub-cache.h
+++ b/deps/v8/src/stub-cache.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_STUB_CACHE_H_
#define V8_STUB_CACHE_H_
@@ -288,15 +265,15 @@ class StubCache {
// Support functions for IC stubs for callbacks.
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty);
+DECLARE_RUNTIME_FUNCTION(StoreCallbackProperty);
// Support functions for IC stubs for interceptors.
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly);
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad);
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall);
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty);
-DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor);
+DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly);
+DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptorForLoad);
+DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptorForCall);
+DECLARE_RUNTIME_FUNCTION(StoreInterceptorProperty);
+DECLARE_RUNTIME_FUNCTION(KeyedLoadPropertyWithInterceptor);
enum PrototypeCheckType { CHECK_ALL_MAPS, SKIP_RECEIVER };
@@ -309,7 +286,7 @@ class StubCompiler BASE_EMBEDDED {
explicit StubCompiler(Isolate* isolate,
ExtraICState extra_ic_state = kNoExtraICState)
: isolate_(isolate), extra_ic_state_(extra_ic_state),
- masm_(isolate, NULL, 256), failure_(NULL) { }
+ masm_(isolate, NULL, 256) { }
Handle<Code> CompileLoadInitialize(Code::Flags flags);
Handle<Code> CompileLoadPreMonomorphic(Code::Flags flags);
@@ -399,8 +376,6 @@ class StubCompiler BASE_EMBEDDED {
Label* miss,
PrototypeCheckType check = CHECK_ALL_MAPS);
- void GenerateBooleanCheck(Register object, Label* miss);
-
static void GenerateFastApiCall(MacroAssembler* masm,
const CallOptimization& optimization,
Handle<Map> receiver_map,
@@ -417,7 +392,6 @@ class StubCompiler BASE_EMBEDDED {
ExtraICState extra_state() { return extra_ic_state_; }
MacroAssembler* masm() { return &masm_; }
- void set_failure(Failure* failure) { failure_ = failure; }
static void LookupPostInterceptor(Handle<JSObject> holder,
Handle<Name> name,
@@ -433,7 +407,6 @@ class StubCompiler BASE_EMBEDDED {
Isolate* isolate_;
const ExtraICState extra_ic_state_;
MacroAssembler masm_;
- Failure* failure_;
};
diff --git a/deps/v8/src/sweeper-thread.cc b/deps/v8/src/sweeper-thread.cc
index 7e8305abe8..e8c8cd68d8 100644
--- a/deps/v8/src/sweeper-thread.cc
+++ b/deps/v8/src/sweeper-thread.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "sweeper-thread.h"
@@ -89,6 +66,15 @@ void SweeperThread::WaitForSweeperThread() {
}
+bool SweeperThread::SweepingCompleted() {
+ bool value = end_sweeping_semaphore_.WaitFor(TimeDelta::FromSeconds(0));
+ if (value) {
+ end_sweeping_semaphore_.Signal();
+ }
+ return value;
+}
+
+
int SweeperThread::NumberOfThreads(int max_available) {
if (!FLAG_concurrent_sweeping && !FLAG_parallel_sweeping) return 0;
if (FLAG_sweeper_threads > 0) return FLAG_sweeper_threads;
diff --git a/deps/v8/src/sweeper-thread.h b/deps/v8/src/sweeper-thread.h
index 3f7917b03f..794e660aa6 100644
--- a/deps/v8/src/sweeper-thread.h
+++ b/deps/v8/src/sweeper-thread.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_SWEEPER_THREAD_H_
#define V8_SWEEPER_THREAD_H_
@@ -31,7 +8,7 @@
#include "atomicops.h"
#include "flags.h"
#include "platform.h"
-#include "v8utils.h"
+#include "utils.h"
#include "spaces.h"
@@ -49,6 +26,7 @@ class SweeperThread : public Thread {
void Stop();
void StartSweeping();
void WaitForSweeperThread();
+ bool SweepingCompleted();
static int NumberOfThreads(int max_available);
diff --git a/deps/v8/src/symbol.js b/deps/v8/src/symbol.js
index e7ea5a68d8..1c48302020 100644
--- a/deps/v8/src/symbol.js
+++ b/deps/v8/src/symbol.js
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
"use strict";
diff --git a/deps/v8/src/third_party/vtune/vtune-jit.cc b/deps/v8/src/third_party/vtune/vtune-jit.cc
index ea897e58e4..023dd1864b 100644
--- a/deps/v8/src/third_party/vtune/vtune-jit.cc
+++ b/deps/v8/src/third_party/vtune/vtune-jit.cc
@@ -196,8 +196,9 @@ void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) {
if (*script != NULL) {
// Get the source file name and set it to jmethod.source_file_name
- if ((*script->GetScriptName())->IsString()) {
- Handle<String> script_name = script->GetScriptName()->ToString();
+ if ((*script->GetUnboundScript()->GetScriptName())->IsString()) {
+ Handle<String> script_name =
+ script->GetUnboundScript()->GetScriptName()->ToString();
temp_file_name = new char[script_name->Utf8Length() + 1];
script_name->WriteUtf8(temp_file_name);
jmethod.source_file_name = temp_file_name;
@@ -224,7 +225,7 @@ void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) {
jmethod.line_number_table[index].Offset =
static_cast<unsigned int>(Iter->pc_);
jmethod.line_number_table[index++].LineNumber =
- script->GetLineNumber(Iter->pos_)+1;
+ script->GetUnboundScript()->GetLineNumber(Iter->pos_)+1;
}
GetEntries()->erase(event->code_start);
}
diff --git a/deps/v8/src/token.cc b/deps/v8/src/token.cc
index 7ba7ed3420..2215d39682 100644
--- a/deps/v8/src/token.cc
+++ b/deps/v8/src/token.cc
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "../include/v8stdint.h"
#include "token.h"
diff --git a/deps/v8/src/token.h b/deps/v8/src/token.h
index 8efaa477b1..822608d698 100644
--- a/deps/v8/src/token.h
+++ b/deps/v8/src/token.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_TOKEN_H_
#define V8_TOKEN_H_
diff --git a/deps/v8/src/transitions-inl.h b/deps/v8/src/transitions-inl.h
index dc1620a07d..8998198609 100644
--- a/deps/v8/src/transitions-inl.h
+++ b/deps/v8/src/transitions-inl.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_TRANSITIONS_INL_H_
#define V8_TRANSITIONS_INL_H_
@@ -88,12 +65,6 @@ FixedArray* TransitionArray::GetPrototypeTransitions() {
}
-HeapObject* TransitionArray::UncheckedPrototypeTransitions() {
- ASSERT(HasPrototypeTransitions());
- return reinterpret_cast<HeapObject*>(get(kPrototypeTransitionsIndex));
-}
-
-
void TransitionArray::SetPrototypeTransitions(FixedArray* transitions,
WriteBarrierMode mode) {
ASSERT(IsFullTransitionArray());
diff --git a/deps/v8/src/transitions.cc b/deps/v8/src/transitions.cc
index 9d3f038947..7fd56cbe23 100644
--- a/deps/v8/src/transitions.cc
+++ b/deps/v8/src/transitions.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -35,23 +12,21 @@ namespace v8 {
namespace internal {
-static MaybeObject* AllocateRaw(Isolate* isolate, int length) {
- // Use FixedArray to not use TransitionArray::cast on incomplete object.
- FixedArray* array;
- MaybeObject* maybe_array = isolate->heap()->AllocateFixedArray(length);
- if (!maybe_array->To(&array)) return maybe_array;
- return array;
+Handle<TransitionArray> TransitionArray::Allocate(Isolate* isolate,
+ int number_of_transitions) {
+ Handle<FixedArray> array =
+ isolate->factory()->NewFixedArray(ToKeyIndex(number_of_transitions));
+ array->set(kPrototypeTransitionsIndex, Smi::FromInt(0));
+ return Handle<TransitionArray>::cast(array);
}
-MaybeObject* TransitionArray::Allocate(Isolate* isolate,
- int number_of_transitions) {
- FixedArray* array;
- MaybeObject* maybe_array =
- AllocateRaw(isolate, ToKeyIndex(number_of_transitions));
- if (!maybe_array->To(&array)) return maybe_array;
- array->set(kPrototypeTransitionsIndex, Smi::FromInt(0));
- return array;
+Handle<TransitionArray> TransitionArray::AllocateSimple(Isolate* isolate,
+ Handle<Map> target) {
+ Handle<FixedArray> array =
+ isolate->factory()->NewFixedArray(kSimpleTransitionSize);
+ array->set(kSimpleTransitionTarget, *target);
+ return Handle<TransitionArray>::cast(array);
}
@@ -69,86 +44,111 @@ static bool InsertionPointFound(Name* key1, Name* key2) {
}
-MaybeObject* TransitionArray::NewWith(SimpleTransitionFlag flag,
- Name* key,
- Map* target,
- Object* back_pointer) {
- TransitionArray* result;
- MaybeObject* maybe_result;
+Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map,
+ Handle<Name> name,
+ Handle<Map> target,
+ SimpleTransitionFlag flag) {
+ Handle<TransitionArray> result;
+ Isolate* isolate = name->GetIsolate();
if (flag == SIMPLE_TRANSITION) {
- maybe_result = AllocateRaw(target->GetIsolate(), kSimpleTransitionSize);
- if (!maybe_result->To(&result)) return maybe_result;
- result->set(kSimpleTransitionTarget, target);
+ result = AllocateSimple(isolate, target);
} else {
- maybe_result = Allocate(target->GetIsolate(), 1);
- if (!maybe_result->To(&result)) return maybe_result;
- result->NoIncrementalWriteBarrierSet(0, key, target);
+ result = Allocate(isolate, 1);
+ result->NoIncrementalWriteBarrierSet(0, *name, *target);
}
- result->set_back_pointer_storage(back_pointer);
+ result->set_back_pointer_storage(map->GetBackPointer());
return result;
}
-MaybeObject* TransitionArray::ExtendToFullTransitionArray() {
- ASSERT(!IsFullTransitionArray());
- int nof = number_of_transitions();
- TransitionArray* result;
- MaybeObject* maybe_result = Allocate(GetIsolate(), nof);
- if (!maybe_result->To(&result)) return maybe_result;
+Handle<TransitionArray> TransitionArray::ExtendToFullTransitionArray(
+ Handle<Map> containing_map) {
+ ASSERT(!containing_map->transitions()->IsFullTransitionArray());
+ int nof = containing_map->transitions()->number_of_transitions();
- if (nof == 1) {
- result->NoIncrementalWriteBarrierCopyFrom(this, kSimpleTransitionIndex, 0);
+ // A transition array may shrink during GC.
+ Handle<TransitionArray> result = Allocate(containing_map->GetIsolate(), nof);
+ DisallowHeapAllocation no_gc;
+ int new_nof = containing_map->transitions()->number_of_transitions();
+ if (new_nof != nof) {
+ ASSERT(new_nof == 0);
+ result->Shrink(ToKeyIndex(0));
+ } else if (nof == 1) {
+ result->NoIncrementalWriteBarrierCopyFrom(
+ containing_map->transitions(), kSimpleTransitionIndex, 0);
}
- result->set_back_pointer_storage(back_pointer_storage());
+ result->set_back_pointer_storage(
+ containing_map->transitions()->back_pointer_storage());
return result;
}
-MaybeObject* TransitionArray::CopyInsert(Name* name, Map* target) {
- TransitionArray* result;
+Handle<TransitionArray> TransitionArray::CopyInsert(Handle<Map> map,
+ Handle<Name> name,
+ Handle<Map> target,
+ SimpleTransitionFlag flag) {
+ if (!map->HasTransitionArray()) {
+ return TransitionArray::NewWith(map, name, target, flag);
+ }
- int number_of_transitions = this->number_of_transitions();
+ int number_of_transitions = map->transitions()->number_of_transitions();
int new_size = number_of_transitions;
- int insertion_index = this->Search(name);
+ int insertion_index = map->transitions()->Search(*name);
if (insertion_index == kNotFound) ++new_size;
- MaybeObject* maybe_array;
- maybe_array = TransitionArray::Allocate(GetIsolate(), new_size);
- if (!maybe_array->To(&result)) return maybe_array;
+ Handle<TransitionArray> result = Allocate(map->GetIsolate(), new_size);
+
+ // The map's transition array may grown smaller during the allocation above as
+ // it was weakly traversed, though it is guaranteed not to disappear. Trim the
+ // result copy if needed, and recompute variables.
+ ASSERT(map->HasTransitionArray());
+ DisallowHeapAllocation no_gc;
+ TransitionArray* array = map->transitions();
+ if (array->number_of_transitions() != number_of_transitions) {
+ ASSERT(array->number_of_transitions() < number_of_transitions);
+
+ number_of_transitions = array->number_of_transitions();
+ new_size = number_of_transitions;
+
+ insertion_index = array->Search(*name);
+ if (insertion_index == kNotFound) ++new_size;
+
+ result->Shrink(ToKeyIndex(new_size));
+ }
- if (HasPrototypeTransitions()) {
- result->SetPrototypeTransitions(GetPrototypeTransitions());
+ if (array->HasPrototypeTransitions()) {
+ result->SetPrototypeTransitions(array->GetPrototypeTransitions());
}
if (insertion_index != kNotFound) {
for (int i = 0; i < number_of_transitions; ++i) {
if (i != insertion_index) {
- result->NoIncrementalWriteBarrierCopyFrom(this, i, i);
+ result->NoIncrementalWriteBarrierCopyFrom(array, i, i);
}
}
- result->NoIncrementalWriteBarrierSet(insertion_index, name, target);
- result->set_back_pointer_storage(back_pointer_storage());
+ result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target);
+ result->set_back_pointer_storage(array->back_pointer_storage());
return result;
}
insertion_index = 0;
for (; insertion_index < number_of_transitions; ++insertion_index) {
- if (InsertionPointFound(GetKey(insertion_index), name)) break;
+ if (InsertionPointFound(array->GetKey(insertion_index), *name)) break;
result->NoIncrementalWriteBarrierCopyFrom(
- this, insertion_index, insertion_index);
+ array, insertion_index, insertion_index);
}
- result->NoIncrementalWriteBarrierSet(insertion_index, name, target);
+ result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target);
for (; insertion_index < number_of_transitions; ++insertion_index) {
result->NoIncrementalWriteBarrierCopyFrom(
- this, insertion_index, insertion_index + 1);
+ array, insertion_index, insertion_index + 1);
}
- result->set_back_pointer_storage(back_pointer_storage());
+ result->set_back_pointer_storage(array->back_pointer_storage());
return result;
}
diff --git a/deps/v8/src/transitions.h b/deps/v8/src/transitions.h
index b2e9839678..7d8e551a58 100644
--- a/deps/v8/src/transitions.h
+++ b/deps/v8/src/transitions.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_TRANSITIONS_H_
#define V8_TRANSITIONS_H_
@@ -85,7 +62,6 @@ class TransitionArray: public FixedArray {
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Object** GetPrototypeTransitionsSlot();
inline bool HasPrototypeTransitions();
- inline HeapObject* UncheckedPrototypeTransitions();
// Returns the number of transitions in the array.
int number_of_transitions() {
@@ -96,30 +72,25 @@ class TransitionArray: public FixedArray {
inline int number_of_entries() { return number_of_transitions(); }
- // Allocate a new transition array with a single entry.
- static MUST_USE_RESULT MaybeObject* NewWith(
- SimpleTransitionFlag flag,
- Name* key,
- Map* target,
- Object* back_pointer);
+ // Creates a FullTransitionArray from a SimpleTransitionArray in
+ // containing_map.
+ static Handle<TransitionArray> ExtendToFullTransitionArray(
+ Handle<Map> containing_map);
- MUST_USE_RESULT MaybeObject* ExtendToFullTransitionArray();
-
- // Copy the transition array, inserting a new transition.
+ // Create a transition array, copying from the owning map if it already has
+ // one, otherwise creating a new one according to flag.
// TODO(verwaest): This should not cause an existing transition to be
// overwritten.
- MUST_USE_RESULT MaybeObject* CopyInsert(Name* name, Map* target);
-
- // Copy a single transition from the origin array.
- inline void NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
- int origin_transition,
- int target_transition);
+ static Handle<TransitionArray> CopyInsert(Handle<Map> map,
+ Handle<Name> name,
+ Handle<Map> target,
+ SimpleTransitionFlag flag);
// Search a transition for a given property name.
inline int Search(Name* name);
// Allocates a TransitionArray.
- MUST_USE_RESULT static MaybeObject* Allocate(
+ static Handle<TransitionArray> Allocate(
Isolate* isolate, int number_of_transitions);
bool IsSimpleTransition() {
@@ -199,10 +170,24 @@ class TransitionArray: public FixedArray {
kTransitionTarget;
}
+ static Handle<TransitionArray> AllocateSimple(
+ Isolate* isolate, Handle<Map> target);
+
+ // Allocate a new transition array with a single entry.
+ static Handle<TransitionArray> NewWith(Handle<Map> map,
+ Handle<Name> name,
+ Handle<Map> target,
+ SimpleTransitionFlag flag);
+
inline void NoIncrementalWriteBarrierSet(int transition_number,
Name* key,
Map* target);
+ // Copy a single transition from the origin array.
+ inline void NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
+ int origin_transition,
+ int target_transition);
+
DISALLOW_IMPLICIT_CONSTRUCTORS(TransitionArray);
};
diff --git a/deps/v8/src/trig-table.h b/deps/v8/src/trig-table.h
index 081c0389ae..7332152a9d 100644
--- a/deps/v8/src/trig-table.h
+++ b/deps/v8/src/trig-table.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_TRIG_TABLE_H_
#define V8_TRIG_TABLE_H_
diff --git a/deps/v8/src/type-info.cc b/deps/v8/src/type-info.cc
index 99b1b3d899..83fcd0f25e 100644
--- a/deps/v8/src/type-info.cc
+++ b/deps/v8/src/type-info.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -43,18 +20,18 @@ namespace internal {
TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
+ Handle<FixedArray> feedback_vector,
Handle<Context> native_context,
Zone* zone)
: native_context_(native_context),
zone_(zone) {
- Object* raw_info = code->type_feedback_info();
- if (raw_info->IsTypeFeedbackInfo()) {
- feedback_vector_ = Handle<FixedArray>(TypeFeedbackInfo::cast(raw_info)->
- feedback_vector());
- }
-
BuildDictionary(code);
ASSERT(dictionary_->IsDictionary());
+ // We make a copy of the feedback vector because a GC could clear
+ // the type feedback info contained therein.
+ // TODO(mvstanton): revisit the decision to copy when we weakly
+ // traverse the feedback vector at GC time.
+ feedback_vector_ = isolate()->factory()->CopyFixedArray(feedback_vector);
}
@@ -136,9 +113,9 @@ bool TypeFeedbackOracle::CallNewIsMonomorphic(int slot) {
byte TypeFeedbackOracle::ForInType(int feedback_vector_slot) {
Handle<Object> value = GetInfo(feedback_vector_slot);
- return value->IsSmi() &&
- Smi::cast(*value)->value() == TypeFeedbackInfo::kForInFastCaseMarker
- ? ForInStatement::FAST_FOR_IN : ForInStatement::SLOW_FOR_IN;
+ return value.is_identical_to(
+ TypeFeedbackInfo::UninitializedSentinel(isolate()))
+ ? ForInStatement::FAST_FOR_IN : ForInStatement::SLOW_FOR_IN;
}
@@ -217,8 +194,8 @@ void TypeFeedbackOracle::CompareType(TypeFeedbackId id,
Handle<Map> map;
Map* raw_map = code->FindFirstMap();
if (raw_map != NULL) {
- map = Map::CurrentMapForDeprecated(handle(raw_map));
- if (!map.is_null() && CanRetainOtherContext(*map, *native_context_)) {
+ if (Map::CurrentMapForDeprecated(handle(raw_map)).ToHandle(&map) &&
+ CanRetainOtherContext(*map, *native_context_)) {
map = Handle<Map>::null();
}
}
@@ -228,7 +205,7 @@ void TypeFeedbackOracle::CompareType(TypeFeedbackId id,
CompareIC::StubInfoToType(
stub_minor_key, left_type, right_type, combined_type, map, zone());
} else if (code->is_compare_nil_ic_stub()) {
- CompareNilICStub stub(code->extra_ic_state());
+ CompareNilICStub stub(isolate(), code->extra_ic_state());
*combined_type = stub.GetType(zone(), map);
*left_type = *right_type = stub.GetInputType(zone(), map);
}
@@ -255,7 +232,7 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
}
Handle<Code> code = Handle<Code>::cast(object);
ASSERT_EQ(Code::BINARY_OP_IC, code->kind());
- BinaryOpIC::State state(code->extra_ic_state());
+ BinaryOpIC::State state(isolate(), code->extra_ic_state());
ASSERT_EQ(op, state.op());
*left = state.GetLeftType(zone());
@@ -277,7 +254,7 @@ Type* TypeFeedbackOracle::CountType(TypeFeedbackId id) {
if (!object->IsCode()) return Type::None(zone());
Handle<Code> code = Handle<Code>::cast(object);
ASSERT_EQ(Code::BINARY_OP_IC, code->kind());
- BinaryOpIC::State state(code->extra_ic_state());
+ BinaryOpIC::State state(isolate(), code->extra_ic_state());
return state.GetLeftType(zone());
}
@@ -286,7 +263,7 @@ void TypeFeedbackOracle::PropertyReceiverTypes(
TypeFeedbackId id, Handle<String> name,
SmallMapList* receiver_types, bool* is_prototype) {
receiver_types->Clear();
- FunctionPrototypeStub proto_stub(Code::LOAD_IC);
+ FunctionPrototypeStub proto_stub(isolate(), Code::LOAD_IC);
*is_prototype = LoadIsStub(id, &proto_stub);
if (!*is_prototype) {
Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC);
@@ -445,8 +422,7 @@ void TypeFeedbackOracle::CreateDictionary(Handle<Code> code,
ZoneList<RelocInfo>* infos) {
AllowHeapAllocation allocation_allowed;
Code* old_code = *code;
- dictionary_ =
- isolate()->factory()->NewUnseededNumberDictionary(infos->length());
+ dictionary_ = UnseededNumberDictionary::New(isolate(), infos->length());
RelocateRelocInfos(infos, old_code, *code);
}
@@ -492,14 +468,11 @@ void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) {
void TypeFeedbackOracle::SetInfo(TypeFeedbackId ast_id, Object* target) {
ASSERT(dictionary_->FindEntry(IdToKey(ast_id)) ==
UnseededNumberDictionary::kNotFound);
- MaybeObject* maybe_result = dictionary_->AtNumberPut(IdToKey(ast_id), target);
- USE(maybe_result);
-#ifdef DEBUG
- Object* result = NULL;
// Dictionary has been allocated with sufficient size for all elements.
- ASSERT(maybe_result->ToObject(&result));
- ASSERT(*dictionary_ == result);
-#endif
+ DisallowHeapAllocation no_need_to_resize_dictionary;
+ HandleScope scope(isolate());
+ USE(UnseededNumberDictionary::AtNumberPut(
+ dictionary_, IdToKey(ast_id), handle(target, isolate())));
}
diff --git a/deps/v8/src/type-info.h b/deps/v8/src/type-info.h
index 5bf653f1c2..24a9edbd33 100644
--- a/deps/v8/src/type-info.h
+++ b/deps/v8/src/type-info.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_TYPE_INFO_H_
#define V8_TYPE_INFO_H_
@@ -44,6 +21,7 @@ class SmallMapList;
class TypeFeedbackOracle: public ZoneObject {
public:
TypeFeedbackOracle(Handle<Code> code,
+ Handle<FixedArray> feedback_vector,
Handle<Context> native_context,
Zone* zone);
diff --git a/deps/v8/src/typedarray.js b/deps/v8/src/typedarray.js
index 109d627008..267d43d514 100644
--- a/deps/v8/src/typedarray.js
+++ b/deps/v8/src/typedarray.js
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
"use strict";
@@ -57,7 +34,7 @@ macro TYPED_ARRAY_CONSTRUCTOR(ARRAY_ID, NAME, ELEMENT_SIZE)
length = ToPositiveInteger(length, "invalid_typed_array_length");
}
- var bufferByteLength = %ArrayBufferGetByteLength(buffer);
+ var bufferByteLength = %_ArrayBufferGetByteLength(buffer);
var offset;
if (IS_UNDEFINED(byteOffset)) {
offset = 0;
@@ -125,7 +102,6 @@ macro TYPED_ARRAY_CONSTRUCTOR(ARRAY_ID, NAME, ELEMENT_SIZE)
}
function NAMEConstructor(arg1, arg2, arg3) {
-
if (%_IsConstructCall()) {
if (IS_ARRAYBUFFER(arg1)) {
NAMEConstructByArrayBuffer(this, arg1, arg2, arg3);
@@ -139,34 +115,52 @@ macro TYPED_ARRAY_CONSTRUCTOR(ARRAY_ID, NAME, ELEMENT_SIZE)
throw MakeTypeError("constructor_not_function", ["NAME"])
}
}
-endmacro
-TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTOR)
+ function NAME_GetBuffer() {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ["NAME.buffer", this]);
+ }
+ return %TypedArrayGetBuffer(this);
+ }
-function TypedArrayGetBuffer() {
- return %TypedArrayGetBuffer(this);
-}
+ function NAME_GetByteLength() {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ["NAME.byteLength", this]);
+ }
+ return %_ArrayBufferViewGetByteLength(this);
+ }
-function TypedArrayGetByteLength() {
- return %TypedArrayGetByteLength(this);
-}
+ function NAME_GetByteOffset() {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ["NAME.byteOffset", this]);
+ }
+ return %_ArrayBufferViewGetByteOffset(this);
+ }
-function TypedArrayGetByteOffset() {
- return %TypedArrayGetByteOffset(this);
-}
+ function NAME_GetLength() {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ["NAME.length", this]);
+ }
+ return %_TypedArrayGetLength(this);
+ }
-function TypedArrayGetLength() {
- return %TypedArrayGetLength(this);
-}
+ var $NAME = global.NAME;
-function CreateSubArray(elementSize, constructor) {
- return function(begin, end) {
+ function NAMESubArray(begin, end) {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ["NAME.subarray", this]);
+ }
var beginInt = TO_INTEGER(begin);
if (!IS_UNDEFINED(end)) {
end = TO_INTEGER(end);
}
- var srcLength = %TypedArrayGetLength(this);
+ var srcLength = %_TypedArrayGetLength(this);
if (beginInt < 0) {
beginInt = MathMax(0, srcLength + beginInt);
} else {
@@ -184,11 +178,14 @@ function CreateSubArray(elementSize, constructor) {
}
var newLength = endInt - beginInt;
var beginByteOffset =
- %TypedArrayGetByteOffset(this) + beginInt * elementSize;
- return new constructor(%TypedArrayGetBuffer(this),
- beginByteOffset, newLength);
+ %_ArrayBufferViewGetByteOffset(this) + beginInt * ELEMENT_SIZE;
+ return new $NAME(%TypedArrayGetBuffer(this),
+ beginByteOffset, newLength);
}
-}
+endmacro
+
+TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTOR)
+
function TypedArraySetFromArrayLike(target, source, sourceLength, offset) {
if (offset > 0) {
@@ -296,34 +293,34 @@ function TypedArraySet(obj, offset) {
// -------------------------------------------------------------------
-function SetupTypedArray(constructor, fun, elementSize) {
+function SetupTypedArrays() {
+macro SETUP_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE)
%CheckIsBootstrapping();
- %SetCode(constructor, fun);
- %FunctionSetPrototype(constructor, new $Object());
+ %SetCode(global.NAME, NAMEConstructor);
+ %FunctionSetPrototype(global.NAME, new $Object());
- %SetProperty(constructor, "BYTES_PER_ELEMENT", elementSize,
+ %SetProperty(global.NAME, "BYTES_PER_ELEMENT", ELEMENT_SIZE,
READ_ONLY | DONT_ENUM | DONT_DELETE);
- %SetProperty(constructor.prototype,
- "constructor", constructor, DONT_ENUM);
- %SetProperty(constructor.prototype,
- "BYTES_PER_ELEMENT", elementSize,
+ %SetProperty(global.NAME.prototype,
+ "constructor", global.NAME, DONT_ENUM);
+ %SetProperty(global.NAME.prototype,
+ "BYTES_PER_ELEMENT", ELEMENT_SIZE,
READ_ONLY | DONT_ENUM | DONT_DELETE);
- InstallGetter(constructor.prototype, "buffer", TypedArrayGetBuffer);
- InstallGetter(constructor.prototype, "byteOffset", TypedArrayGetByteOffset);
- InstallGetter(constructor.prototype, "byteLength", TypedArrayGetByteLength);
- InstallGetter(constructor.prototype, "length", TypedArrayGetLength);
+ InstallGetter(global.NAME.prototype, "buffer", NAME_GetBuffer);
+ InstallGetter(global.NAME.prototype, "byteOffset", NAME_GetByteOffset);
+ InstallGetter(global.NAME.prototype, "byteLength", NAME_GetByteLength);
+ InstallGetter(global.NAME.prototype, "length", NAME_GetLength);
- InstallFunctions(constructor.prototype, DONT_ENUM, $Array(
- "subarray", CreateSubArray(elementSize, constructor),
+ InstallFunctions(global.NAME.prototype, DONT_ENUM, $Array(
+ "subarray", NAMESubArray,
"set", TypedArraySet
));
-}
-
-macro SETUP_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE)
- SetupTypedArray (global.NAME, NAMEConstructor, ELEMENT_SIZE);
endmacro
TYPED_ARRAYS(SETUP_TYPED_ARRAY)
+}
+
+SetupTypedArrays();
// --------------------------- DataView -----------------------------
@@ -341,7 +338,7 @@ function DataViewConstructor(buffer, byteOffset, byteLength) { // length = 3
byteLength = TO_INTEGER(byteLength);
}
- var bufferByteLength = %ArrayBufferGetByteLength(buffer);
+ var bufferByteLength = %_ArrayBufferGetByteLength(buffer);
var offset = IS_UNDEFINED(byteOffset) ? 0 : byteOffset;
if (offset > bufferByteLength) {
@@ -373,7 +370,7 @@ function DataViewGetByteOffset() {
throw MakeTypeError('incompatible_method_receiver',
['DataView.byteOffset', this]);
}
- return %DataViewGetByteOffset(this);
+ return %_ArrayBufferViewGetByteOffset(this);
}
function DataViewGetByteLength() {
@@ -381,7 +378,7 @@ function DataViewGetByteLength() {
throw MakeTypeError('incompatible_method_receiver',
['DataView.byteLength', this]);
}
- return %DataViewGetByteLength(this);
+ return %_ArrayBufferViewGetByteLength(this);
}
macro DATA_VIEW_TYPES(FUNCTION)
diff --git a/deps/v8/src/types-inl.h b/deps/v8/src/types-inl.h
new file mode 100644
index 0000000000..ca4f120c79
--- /dev/null
+++ b/deps/v8/src/types-inl.h
@@ -0,0 +1,352 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_TYPES_INL_H_
+#define V8_TYPES_INL_H_
+
+#include "types.h"
+
+#include "factory.h"
+#include "handles-inl.h"
+
+namespace v8 {
+namespace internal {
+
+// -------------------------------------------------------------------------- //
+// TypeImpl
+
+template<class Config>
+TypeImpl<Config>* TypeImpl<Config>::cast(typename Config::Base* object) {
+ TypeImpl* t = static_cast<TypeImpl*>(object);
+ ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() ||
+ t->IsUnion() || t->IsArray() || t->IsFunction());
+ return t;
+}
+
+
+template<class Config>
+bool TypeImpl<Config>::NowContains(i::Object* value) {
+ DisallowHeapAllocation no_allocation;
+ if (this->IsAny()) return true;
+ if (value->IsHeapObject()) {
+ i::Map* map = i::HeapObject::cast(value)->map();
+ for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) {
+ if (*it.Current() == map) return true;
+ }
+ }
+ return this->Contains(value);
+}
+
+
+// -------------------------------------------------------------------------- //
+// ZoneTypeConfig
+
+// static
+template<class T>
+T* ZoneTypeConfig::handle(T* type) {
+ return type;
+}
+
+
+// static
+template<class T>
+T* ZoneTypeConfig::cast(Type* type) {
+ return static_cast<T*>(type);
+}
+
+
+// static
+bool ZoneTypeConfig::is_bitset(Type* type) {
+ return reinterpret_cast<intptr_t>(type) & 1;
+}
+
+
+// static
+bool ZoneTypeConfig::is_struct(Type* type, int tag) {
+ return !is_bitset(type) && struct_tag(as_struct(type)) == tag;
+}
+
+
+// static
+bool ZoneTypeConfig::is_class(Type* type) {
+ return is_struct(type, Type::StructuralType::kClassTag);
+}
+
+
+// static
+bool ZoneTypeConfig::is_constant(Type* type) {
+ return is_struct(type, Type::StructuralType::kConstantTag);
+}
+
+
+// static
+int ZoneTypeConfig::as_bitset(Type* type) {
+ ASSERT(is_bitset(type));
+ return static_cast<int>(reinterpret_cast<intptr_t>(type) >> 1);
+}
+
+
+// static
+ZoneTypeConfig::Struct* ZoneTypeConfig::as_struct(Type* type) {
+ ASSERT(!is_bitset(type));
+ return reinterpret_cast<Struct*>(type);
+}
+
+
+// static
+i::Handle<i::Map> ZoneTypeConfig::as_class(Type* type) {
+ ASSERT(is_class(type));
+ return i::Handle<i::Map>(static_cast<i::Map**>(as_struct(type)[3]));
+}
+
+
+// static
+i::Handle<i::Object> ZoneTypeConfig::as_constant(Type* type) {
+ ASSERT(is_constant(type));
+ return i::Handle<i::Object>(
+ static_cast<i::Object**>(as_struct(type)[3]));
+}
+
+
+// static
+ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(int bitset) {
+ return reinterpret_cast<Type*>((bitset << 1) | 1);
+}
+
+
+// static
+ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(int bitset, Zone* Zone) {
+ return from_bitset(bitset);
+}
+
+
+// static
+ZoneTypeConfig::Type* ZoneTypeConfig::from_struct(Struct* structured) {
+ return reinterpret_cast<Type*>(structured);
+}
+
+
+// static
+ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
+ i::Handle<i::Map> map, int lub, Zone* zone) {
+ Struct* structured = struct_create(Type::StructuralType::kClassTag, 2, zone);
+ structured[2] = from_bitset(lub);
+ structured[3] = map.location();
+ return from_struct(structured);
+}
+
+
+// static
+ZoneTypeConfig::Type* ZoneTypeConfig::from_constant(
+ i::Handle<i::Object> value, int lub, Zone* zone) {
+ Struct* structured =
+ struct_create(Type::StructuralType::kConstantTag, 2, zone);
+ structured[2] = from_bitset(lub);
+ structured[3] = value.location();
+ return from_struct(structured);
+}
+
+
+// static
+ZoneTypeConfig::Struct* ZoneTypeConfig::struct_create(
+ int tag, int length, Zone* zone) {
+ Struct* structured = reinterpret_cast<Struct*>(
+ zone->New(sizeof(void*) * (length + 2))); // NOLINT
+ structured[0] = reinterpret_cast<void*>(tag);
+ structured[1] = reinterpret_cast<void*>(length);
+ return structured;
+}
+
+
+// static
+void ZoneTypeConfig::struct_shrink(Struct* structured, int length) {
+ ASSERT(0 <= length && length <= struct_length(structured));
+ structured[1] = reinterpret_cast<void*>(length);
+}
+
+
+// static
+int ZoneTypeConfig::struct_tag(Struct* structured) {
+ return static_cast<int>(reinterpret_cast<intptr_t>(structured[0]));
+}
+
+
+// static
+int ZoneTypeConfig::struct_length(Struct* structured) {
+ return static_cast<int>(reinterpret_cast<intptr_t>(structured[1]));
+}
+
+
+// static
+Type* ZoneTypeConfig::struct_get(Struct* structured, int i) {
+ ASSERT(0 <= i && i <= struct_length(structured));
+ return static_cast<Type*>(structured[2 + i]);
+}
+
+
+// static
+void ZoneTypeConfig::struct_set(Struct* structured, int i, Type* type) {
+ ASSERT(0 <= i && i <= struct_length(structured));
+ structured[2 + i] = type;
+}
+
+
+// static
+int ZoneTypeConfig::lub_bitset(Type* type) {
+ ASSERT(is_class(type) || is_constant(type));
+ return as_bitset(struct_get(as_struct(type), 0));
+}
+
+
+// -------------------------------------------------------------------------- //
+// HeapTypeConfig
+
+// static
+template<class T>
+i::Handle<T> HeapTypeConfig::handle(T* type) {
+ return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
+}
+
+
+// static
+template<class T>
+i::Handle<T> HeapTypeConfig::cast(i::Handle<Type> type) {
+ return i::Handle<T>::cast(type);
+}
+
+
+// static
+bool HeapTypeConfig::is_bitset(Type* type) {
+ return type->IsSmi();
+}
+
+
+// static
+bool HeapTypeConfig::is_class(Type* type) {
+ return type->IsMap();
+}
+
+
+// static
+bool HeapTypeConfig::is_constant(Type* type) {
+ return type->IsBox();
+}
+
+
+// static
+bool HeapTypeConfig::is_struct(Type* type, int tag) {
+ return type->IsFixedArray() && struct_tag(as_struct(type)) == tag;
+}
+
+
+// static
+int HeapTypeConfig::as_bitset(Type* type) {
+ return i::Smi::cast(type)->value();
+}
+
+
+// static
+i::Handle<i::Map> HeapTypeConfig::as_class(Type* type) {
+ return i::handle(i::Map::cast(type));
+}
+
+
+// static
+i::Handle<i::Object> HeapTypeConfig::as_constant(Type* type) {
+ i::Box* box = i::Box::cast(type);
+ return i::handle(box->value(), box->GetIsolate());
+}
+
+
+// static
+i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::as_struct(Type* type) {
+ return i::handle(Struct::cast(type));
+}
+
+
+// static
+HeapTypeConfig::Type* HeapTypeConfig::from_bitset(int bitset) {
+ return Type::cast(i::Smi::FromInt(bitset));
+}
+
+
+// static
+i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_bitset(
+ int bitset, Isolate* isolate) {
+ return i::handle(from_bitset(bitset), isolate);
+}
+
+
+// static
+i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_class(
+ i::Handle<i::Map> map, int lub, Isolate* isolate) {
+ return i::Handle<Type>::cast(i::Handle<Object>::cast(map));
+}
+
+
+// static
+i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_constant(
+ i::Handle<i::Object> value, int lub, Isolate* isolate) {
+ i::Handle<Box> box = isolate->factory()->NewBox(value);
+ return i::Handle<Type>::cast(i::Handle<Object>::cast(box));
+}
+
+
+// static
+i::Handle<HeapTypeConfig::Type> HeapTypeConfig::from_struct(
+ i::Handle<Struct> structured) {
+ return i::Handle<Type>::cast(i::Handle<Object>::cast(structured));
+}
+
+
+// static
+i::Handle<HeapTypeConfig::Struct> HeapTypeConfig::struct_create(
+ int tag, int length, Isolate* isolate) {
+ i::Handle<Struct> structured = isolate->factory()->NewFixedArray(length + 1);
+ structured->set(0, i::Smi::FromInt(tag));
+ return structured;
+}
+
+
+// static
+void HeapTypeConfig::struct_shrink(i::Handle<Struct> structured, int length) {
+ structured->Shrink(length + 1);
+}
+
+
+// static
+int HeapTypeConfig::struct_tag(i::Handle<Struct> structured) {
+ return static_cast<i::Smi*>(structured->get(0))->value();
+}
+
+
+// static
+int HeapTypeConfig::struct_length(i::Handle<Struct> structured) {
+ return structured->length() - 1;
+}
+
+
+// static
+i::Handle<HeapTypeConfig::Type> HeapTypeConfig::struct_get(
+ i::Handle<Struct> structured, int i) {
+ Type* type = static_cast<Type*>(structured->get(i + 1));
+ return i::handle(type, structured->GetIsolate());
+}
+
+
+// static
+void HeapTypeConfig::struct_set(
+ i::Handle<Struct> structured, int i, i::Handle<Type> type) {
+ structured->set(i + 1, *type);
+}
+
+
+// static
+int HeapTypeConfig::lub_bitset(Type* type) {
+ return 0; // kNone, which causes recomputation.
+}
+
+} } // namespace v8::internal
+
+#endif // V8_TYPES_INL_H_
diff --git a/deps/v8/src/types.cc b/deps/v8/src/types.cc
index e269582ca0..5270c0ea6d 100644
--- a/deps/v8/src/types.cc
+++ b/deps/v8/src/types.cc
@@ -1,45 +1,25 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "types.h"
+
#include "string-stream.h"
+#include "types-inl.h"
namespace v8 {
namespace internal {
template<class Config>
int TypeImpl<Config>::NumClasses() {
+ DisallowHeapAllocation no_allocation;
if (this->IsClass()) {
return 1;
} else if (this->IsUnion()) {
- UnionedHandle unioned = this->AsUnion();
+ UnionHandle unioned = handle(this->AsUnion());
int result = 0;
- for (int i = 0; i < Config::union_length(unioned); ++i) {
- if (Config::union_get(unioned, i)->IsClass()) ++result;
+ for (int i = 0; i < unioned->Length(); ++i) {
+ if (unioned->Get(i)->IsClass()) ++result;
}
return result;
} else {
@@ -50,13 +30,14 @@ int TypeImpl<Config>::NumClasses() {
template<class Config>
int TypeImpl<Config>::NumConstants() {
+ DisallowHeapAllocation no_allocation;
if (this->IsConstant()) {
return 1;
} else if (this->IsUnion()) {
- UnionedHandle unioned = this->AsUnion();
+ UnionHandle unioned = handle(this->AsUnion());
int result = 0;
- for (int i = 0; i < Config::union_length(unioned); ++i) {
- if (Config::union_get(unioned, i)->IsConstant()) ++result;
+ for (int i = 0; i < unioned->Length(); ++i) {
+ if (unioned->Get(i)->IsConstant()) ++result;
}
return result;
} else {
@@ -69,7 +50,7 @@ template<class Config> template<class T>
typename TypeImpl<Config>::TypeHandle
TypeImpl<Config>::Iterator<T>::get_type() {
ASSERT(!Done());
- return type_->IsUnion() ? Config::union_get(type_->AsUnion(), index_) : type_;
+ return type_->IsUnion() ? type_->AsUnion()->Get(index_) : type_;
}
@@ -87,7 +68,7 @@ struct TypeImplIteratorAux<Config, i::Map> {
return type->IsClass();
}
static i::Handle<i::Map> current(typename TypeImpl<Config>::TypeHandle type) {
- return type->AsClass();
+ return type->AsClass()->Map();
}
};
@@ -98,7 +79,7 @@ struct TypeImplIteratorAux<Config, i::Object> {
}
static i::Handle<i::Object> current(
typename TypeImpl<Config>::TypeHandle type) {
- return type->AsConstant();
+ return type->AsConstant()->Value();
}
};
@@ -115,11 +96,12 @@ i::Handle<T> TypeImpl<Config>::Iterator<T>::Current() {
template<class Config> template<class T>
void TypeImpl<Config>::Iterator<T>::Advance() {
+ DisallowHeapAllocation no_allocation;
++index_;
if (type_->IsUnion()) {
- UnionedHandle unioned = type_->AsUnion();
- for (; index_ < Config::union_length(unioned); ++index_) {
- if (matches(Config::union_get(unioned, index_))) return;
+ UnionHandle unioned = handle(type_->AsUnion());
+ for (; index_ < unioned->Length(); ++index_) {
+ if (matches(unioned->Get(index_))) return;
}
} else if (index_ == 0 && matches(type_)) {
return;
@@ -128,30 +110,54 @@ void TypeImpl<Config>::Iterator<T>::Advance() {
}
+// Get the largest bitset subsumed by this type.
+template<class Config>
+int TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) {
+ DisallowHeapAllocation no_allocation;
+ if (type->IsBitset()) {
+ return type->AsBitset();
+ } else if (type->IsUnion()) {
+ // All but the first are non-bitsets and thus would yield kNone anyway.
+ return type->AsUnion()->Get(0)->BitsetGlb();
+ } else {
+ return kNone;
+ }
+}
+
+
// Get the smallest bitset subsuming this type.
template<class Config>
-int TypeImpl<Config>::LubBitset() {
- if (this->IsBitset()) {
- return this->AsBitset();
- } else if (this->IsUnion()) {
- UnionedHandle unioned = this->AsUnion();
+int TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) {
+ DisallowHeapAllocation no_allocation;
+ if (type->IsBitset()) {
+ return type->AsBitset();
+ } else if (type->IsUnion()) {
+ UnionHandle unioned = handle(type->AsUnion());
int bitset = kNone;
- for (int i = 0; i < Config::union_length(unioned); ++i) {
- bitset |= Config::union_get(unioned, i)->LubBitset();
+ for (int i = 0; i < unioned->Length(); ++i) {
+ bitset |= unioned->Get(i)->BitsetLub();
}
return bitset;
- } else if (this->IsClass()) {
- int bitset = Config::lub_bitset(this);
- return bitset ? bitset : LubBitset(*this->AsClass());
+ } else if (type->IsClass()) {
+ int bitset = Config::lub_bitset(type);
+ return bitset ? bitset : Lub(*type->AsClass()->Map());
+ } else if (type->IsConstant()) {
+ int bitset = Config::lub_bitset(type);
+ return bitset ? bitset : Lub(*type->AsConstant()->Value());
+ } else if (type->IsArray()) {
+ return kArray;
+ } else if (type->IsFunction()) {
+ return kFunction;
} else {
- int bitset = Config::lub_bitset(this);
- return bitset ? bitset : LubBitset(*this->AsConstant());
+ UNREACHABLE();
+ return kNone;
}
}
template<class Config>
-int TypeImpl<Config>::LubBitset(i::Object* value) {
+int TypeImpl<Config>::BitsetType::Lub(i::Object* value) {
+ DisallowHeapAllocation no_allocation;
if (value->IsSmi()) return kSignedSmall & kTaggedInt;
i::Map* map = i::HeapObject::cast(value)->map();
if (map->instance_type() == HEAP_NUMBER_TYPE) {
@@ -161,20 +167,13 @@ int TypeImpl<Config>::LubBitset(i::Object* value) {
value->ToInt32(&i) ? (Smi::IsValid(i) ? kSignedSmall : kOtherSigned32) :
value->ToUint32(&u) ? kUnsigned32 : kFloat);
}
- if (map->instance_type() == ODDBALL_TYPE) {
- if (value->IsUndefined()) return kUndefined;
- if (value->IsNull()) return kNull;
- if (value->IsBoolean()) return kBoolean;
- if (value->IsTheHole()) return kAny; // TODO(rossberg): kNone?
- if (value->IsUninitialized()) return kNone;
- UNREACHABLE();
- }
- return LubBitset(map);
+ return Lub(map);
}
template<class Config>
-int TypeImpl<Config>::LubBitset(i::Map* map) {
+int TypeImpl<Config>::BitsetType::Lub(i::Map* map) {
+ DisallowHeapAllocation no_allocation;
switch (map->instance_type()) {
case STRING_TYPE:
case ASCII_STRING_TYPE:
@@ -190,8 +189,6 @@ int TypeImpl<Config>::LubBitset(i::Map* map) {
case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
case INTERNALIZED_STRING_TYPE:
case ASCII_INTERNALIZED_STRING_TYPE:
- case CONS_INTERNALIZED_STRING_TYPE:
- case CONS_ASCII_INTERNALIZED_STRING_TYPE:
case EXTERNAL_INTERNALIZED_STRING_TYPE:
case EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE:
case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
@@ -201,8 +198,18 @@ int TypeImpl<Config>::LubBitset(i::Map* map) {
return kString;
case SYMBOL_TYPE:
return kSymbol;
- case ODDBALL_TYPE:
- return kOddball;
+ case ODDBALL_TYPE: {
+ Heap* heap = map->GetHeap();
+ if (map == heap->undefined_map()) return kUndefined;
+ if (map == heap->the_hole_map()) return kAny; // TODO(rossberg): kNone?
+ if (map == heap->null_map()) return kNull;
+ if (map == heap->boolean_map()) return kBoolean;
+ ASSERT(map == heap->uninitialized_map() ||
+ map == heap->no_interceptor_result_sentinel_map() ||
+ map == heap->termination_exception_map() ||
+ map == heap->arguments_marker_map());
+ return kInternal & kTaggedPtr;
+ }
case HEAP_NUMBER_TYPE:
return kFloat & kTaggedPtr;
case JS_VALUE_TYPE:
@@ -219,6 +226,8 @@ int TypeImpl<Config>::LubBitset(i::Map* map) {
case JS_DATA_VIEW_TYPE:
case JS_SET_TYPE:
case JS_MAP_TYPE:
+ case JS_SET_ITERATOR_TYPE:
+ case JS_MAP_ITERATOR_TYPE:
case JS_WEAK_MAP_TYPE:
case JS_WEAK_SET_TYPE:
if (map->is_undetectable()) return kUndetectable;
@@ -247,6 +256,7 @@ int TypeImpl<Config>::LubBitset(i::Map* map) {
case EXECUTABLE_ACCESSOR_INFO_TYPE:
case ACCESSOR_PAIR_TYPE:
case FIXED_ARRAY_TYPE:
+ case FOREIGN_TYPE:
return kInternal & kTaggedPtr;
default:
UNREACHABLE();
@@ -255,55 +265,63 @@ int TypeImpl<Config>::LubBitset(i::Map* map) {
}
-// Get the largest bitset subsumed by this type.
-template<class Config>
-int TypeImpl<Config>::GlbBitset() {
- if (this->IsBitset()) {
- return this->AsBitset();
- } else if (this->IsUnion()) {
- // All but the first are non-bitsets and thus would yield kNone anyway.
- return Config::union_get(this->AsUnion(), 0)->GlbBitset();
- } else {
- return kNone;
- }
-}
-
-
// Most precise _current_ type of a value (usually its class).
template<class Config>
-typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::OfCurrently(
- i::Handle<i::Object> value, Region* region) {
+typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NowOf(
+ i::Object* value, Region* region) {
if (value->IsSmi() ||
- i::HeapObject::cast(*value)->map()->instance_type() == HEAP_NUMBER_TYPE ||
- i::HeapObject::cast(*value)->map()->instance_type() == ODDBALL_TYPE) {
+ i::HeapObject::cast(value)->map()->instance_type() == HEAP_NUMBER_TYPE) {
return Of(value, region);
}
- return Class(i::handle(i::HeapObject::cast(*value)->map()), region);
+ return Class(i::handle(i::HeapObject::cast(value)->map()), region);
}
// Check this <= that.
template<class Config>
bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
+ DisallowHeapAllocation no_allocation;
+
// Fast path for bitsets.
if (this->IsNone()) return true;
if (that->IsBitset()) {
- return (this->LubBitset() | that->AsBitset()) == that->AsBitset();
+ return (BitsetType::Lub(this) | that->AsBitset()) == that->AsBitset();
}
if (that->IsClass()) {
- return this->IsClass() && *this->AsClass() == *that->AsClass();
+ return this->IsClass()
+ && *this->AsClass()->Map() == *that->AsClass()->Map();
}
if (that->IsConstant()) {
- return this->IsConstant() && *this->AsConstant() == *that->AsConstant();
+ return this->IsConstant()
+ && *this->AsConstant()->Value() == *that->AsConstant()->Value();
+ }
+ if (that->IsArray()) {
+ return this->IsArray()
+ && this->AsArray()->Element()->Equals(that->AsArray()->Element());
+ }
+ if (that->IsFunction()) {
+ // We currently do not allow for any variance here, in order to keep
+ // Union and Intersect operations simple.
+ if (!this->IsFunction()) return false;
+ FunctionType* this_fun = this->AsFunction();
+ FunctionType* that_fun = that->AsFunction();
+ if (this_fun->Arity() != that_fun->Arity() ||
+ !this_fun->Result()->Equals(that_fun->Result()) ||
+ !that_fun->Receiver()->Equals(this_fun->Receiver())) {
+ return false;
+ }
+ for (int i = 0; i < this_fun->Arity(); ++i) {
+ if (!that_fun->Parameter(i)->Equals(this_fun->Parameter(i))) return false;
+ }
+ return true;
}
// (T1 \/ ... \/ Tn) <= T <=> (T1 <= T) /\ ... /\ (Tn <= T)
if (this->IsUnion()) {
- UnionedHandle unioned = this->AsUnion();
- for (int i = 0; i < Config::union_length(unioned); ++i) {
- TypeHandle this_i = Config::union_get(unioned, i);
- if (!this_i->Is(that)) return false;
+ UnionHandle unioned = handle(this->AsUnion());
+ for (int i = 0; i < unioned->Length(); ++i) {
+ if (!unioned->Get(i)->Is(that)) return false;
}
return true;
}
@@ -312,10 +330,9 @@ bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
// (iff T is not a union)
ASSERT(!this->IsUnion());
if (that->IsUnion()) {
- UnionedHandle unioned = that->AsUnion();
- for (int i = 0; i < Config::union_length(unioned); ++i) {
- TypeHandle that_i = Config::union_get(unioned, i);
- if (this->Is(that_i)) return true;
+ UnionHandle unioned = handle(that->AsUnion());
+ for (int i = 0; i < unioned->Length(); ++i) {
+ if (this->Is(unioned->Get(i))) return true;
if (this->IsBitset()) break; // Fast fail, only first field is a bitset.
}
return false;
@@ -326,51 +343,81 @@ bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
template<class Config>
-bool TypeImpl<Config>::IsCurrently(TypeImpl* that) {
- return this->Is(that) ||
- (this->IsConstant() && that->IsClass() &&
- this->AsConstant()->IsHeapObject() &&
- i::HeapObject::cast(*this->AsConstant())->map() == *that->AsClass());
+bool TypeImpl<Config>::NowIs(TypeImpl* that) {
+ DisallowHeapAllocation no_allocation;
+
+ // TODO(rossberg): this is incorrect for
+ // Union(Constant(V), T)->NowIs(Class(M))
+ // but fuzzing does not cover that!
+ if (this->IsConstant()) {
+ i::Object* object = *this->AsConstant()->Value();
+ if (object->IsHeapObject()) {
+ i::Map* map = i::HeapObject::cast(object)->map();
+ for (Iterator<i::Map> it = that->Classes(); !it.Done(); it.Advance()) {
+ if (*it.Current() == map) return true;
+ }
+ }
+ }
+ return this->Is(that);
+}
+
+
+// Check if this contains only (currently) stable classes.
+template<class Config>
+bool TypeImpl<Config>::NowStable() {
+ DisallowHeapAllocation no_allocation;
+ for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) {
+ if (!it.Current()->is_stable()) return false;
+ }
+ return true;
}
// Check this overlaps that.
template<class Config>
bool TypeImpl<Config>::Maybe(TypeImpl* that) {
- // Fast path for bitsets.
- if (this->IsBitset()) {
- return IsInhabited(this->AsBitset() & that->LubBitset());
- }
- if (that->IsBitset()) {
- return IsInhabited(this->LubBitset() & that->AsBitset());
- }
+ DisallowHeapAllocation no_allocation;
// (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T)
if (this->IsUnion()) {
- UnionedHandle unioned = this->AsUnion();
- for (int i = 0; i < Config::union_length(unioned); ++i) {
- TypeHandle this_i = Config::union_get(unioned, i);
- if (this_i->Maybe(that)) return true;
+ UnionHandle unioned = handle(this->AsUnion());
+ for (int i = 0; i < unioned->Length(); ++i) {
+ if (unioned->Get(i)->Maybe(that)) return true;
}
return false;
}
// T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn)
if (that->IsUnion()) {
- UnionedHandle unioned = that->AsUnion();
- for (int i = 0; i < Config::union_length(unioned); ++i) {
- TypeHandle that_i = Config::union_get(unioned, i);
- if (this->Maybe(that_i)) return true;
+ UnionHandle unioned = handle(that->AsUnion());
+ for (int i = 0; i < unioned->Length(); ++i) {
+ if (this->Maybe(unioned->Get(i))) return true;
}
return false;
}
ASSERT(!this->IsUnion() && !that->IsUnion());
+ if (this->IsBitset()) {
+ return BitsetType::IsInhabited(this->AsBitset() & that->BitsetLub());
+ }
+ if (that->IsBitset()) {
+ return BitsetType::IsInhabited(this->BitsetLub() & that->AsBitset());
+ }
if (this->IsClass()) {
- return that->IsClass() && *this->AsClass() == *that->AsClass();
+ return that->IsClass()
+ && *this->AsClass()->Map() == *that->AsClass()->Map();
}
if (this->IsConstant()) {
- return that->IsConstant() && *this->AsConstant() == *that->AsConstant();
+ return that->IsConstant()
+ && *this->AsConstant()->Value() == *that->AsConstant()->Value();
+ }
+ if (this->IsArray()) {
+ // There is no variance!
+ return this->Equals(that);
+ }
+ if (this->IsFunction()) {
+ // There is no variance!
+ return this->Equals(that);
}
return false;
@@ -378,56 +425,65 @@ bool TypeImpl<Config>::Maybe(TypeImpl* that) {
template<class Config>
-bool TypeImpl<Config>::InUnion(UnionedHandle unioned, int current_size) {
+bool TypeImpl<Config>::Contains(i::Object* value) {
+ DisallowHeapAllocation no_allocation;
+
+ for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) {
+ if (*it.Current() == value) return true;
+ }
+ return BitsetType::New(BitsetType::Lub(value))->Is(this);
+}
+
+
+template<class Config>
+bool TypeImpl<Config>::InUnion(UnionHandle unioned, int current_size) {
ASSERT(!this->IsUnion());
for (int i = 0; i < current_size; ++i) {
- TypeHandle type = Config::union_get(unioned, i);
- if (this->Is(type)) return true;
+ if (this->Is(unioned->Get(i))) return true;
}
return false;
}
-// Get non-bitsets from this which are not subsumed by union, store at unioned,
+// Get non-bitsets from this which are not subsumed by union, store at result,
// starting at index. Returns updated index.
template<class Config>
int TypeImpl<Config>::ExtendUnion(
- UnionedHandle result, TypeHandle type, int current_size) {
+ UnionHandle result, TypeHandle type, int current_size) {
int old_size = current_size;
- if (type->IsClass() || type->IsConstant()) {
- if (!type->InUnion(result, old_size)) {
- Config::union_set(result, current_size++, type);
- }
- } else if (type->IsUnion()) {
- UnionedHandle unioned = type->AsUnion();
- for (int i = 0; i < Config::union_length(unioned); ++i) {
- TypeHandle type = Config::union_get(unioned, i);
- ASSERT(i == 0 ||
- !(type->IsBitset() || type->Is(Config::union_get(unioned, 0))));
+ if (type->IsUnion()) {
+ UnionHandle unioned = handle(type->AsUnion());
+ for (int i = 0; i < unioned->Length(); ++i) {
+ TypeHandle type = unioned->Get(i);
+ ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0))));
if (!type->IsBitset() && !type->InUnion(result, old_size)) {
- Config::union_set(result, current_size++, type);
+ result->Set(current_size++, type);
}
}
+ } else if (!type->IsBitset()) {
+ // For all structural types, subtyping implies equivalence.
+ ASSERT(type->IsClass() || type->IsConstant() ||
+ type->IsArray() || type->IsFunction());
+ if (!type->InUnion(result, old_size)) {
+ result->Set(current_size++, type);
+ }
}
return current_size;
}
// Union is O(1) on simple bit unions, but O(n*m) on structured unions.
-// TODO(rossberg): Should we use object sets somehow? Is it worth it?
template<class Config>
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
TypeHandle type1, TypeHandle type2, Region* region) {
// Fast case: bit sets.
if (type1->IsBitset() && type2->IsBitset()) {
- return Config::from_bitset(type1->AsBitset() | type2->AsBitset(), region);
+ return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region);
}
// Fast case: top or bottom types.
- if (type1->IsAny()) return type1;
- if (type2->IsAny()) return type2;
- if (type1->IsNone()) return type2;
- if (type2->IsNone()) return type1;
+ if (type1->IsAny() || type2->IsNone()) return type1;
+ if (type2->IsAny() || type1->IsNone()) return type2;
// Semi-fast case: Unioned objects are neither involved nor produced.
if (!(type1->IsUnion() || type2->IsUnion())) {
@@ -436,74 +492,74 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
}
// Slow case: may need to produce a Unioned object.
- int size = type1->IsBitset() || type2->IsBitset() ? 1 : 0;
+ int size = 0;
if (!type1->IsBitset()) {
- size += (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1);
+ size += (type1->IsUnion() ? type1->AsUnion()->Length() : 1);
}
if (!type2->IsBitset()) {
- size += (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1);
+ size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1);
}
- ASSERT(size >= 2);
- UnionedHandle unioned = Config::union_create(size, region);
- size = 0;
+ int bitset = type1->BitsetGlb() | type2->BitsetGlb();
+ if (bitset != BitsetType::kNone) ++size;
+ ASSERT(size >= 1);
- int bitset = type1->GlbBitset() | type2->GlbBitset();
- if (bitset != kNone) {
- Config::union_set(unioned, size++, Config::from_bitset(bitset, region));
+ UnionHandle unioned = UnionType::New(size, region);
+ size = 0;
+ if (bitset != BitsetType::kNone) {
+ unioned->Set(size++, BitsetType::New(bitset, region));
}
size = ExtendUnion(unioned, type1, size);
size = ExtendUnion(unioned, type2, size);
if (size == 1) {
- return Config::union_get(unioned, 0);
+ return unioned->Get(0);
} else {
- Config::union_shrink(unioned, size);
- return Config::from_union(unioned);
+ unioned->Shrink(size);
+ return unioned;
}
}
-// Get non-bitsets from type which are also in other, store at unioned,
+// Get non-bitsets from type which are also in other, store at result,
// starting at index. Returns updated index.
template<class Config>
int TypeImpl<Config>::ExtendIntersection(
- UnionedHandle result, TypeHandle type, TypeHandle other, int current_size) {
+ UnionHandle result, TypeHandle type, TypeHandle other, int current_size) {
int old_size = current_size;
- if (type->IsClass() || type->IsConstant()) {
- if (type->Is(other) && !type->InUnion(result, old_size)) {
- Config::union_set(result, current_size++, type);
- }
- } else if (type->IsUnion()) {
- UnionedHandle unioned = type->AsUnion();
- for (int i = 0; i < Config::union_length(unioned); ++i) {
- TypeHandle type = Config::union_get(unioned, i);
- ASSERT(i == 0 ||
- !(type->IsBitset() || type->Is(Config::union_get(unioned, 0))));
+ if (type->IsUnion()) {
+ UnionHandle unioned = handle(type->AsUnion());
+ for (int i = 0; i < unioned->Length(); ++i) {
+ TypeHandle type = unioned->Get(i);
+ ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0))));
if (!type->IsBitset() && type->Is(other) &&
!type->InUnion(result, old_size)) {
- Config::union_set(result, current_size++, type);
+ result->Set(current_size++, type);
}
}
+ } else if (!type->IsBitset()) {
+ // For all structural types, subtyping implies equivalence.
+ ASSERT(type->IsClass() || type->IsConstant() ||
+ type->IsArray() || type->IsFunction());
+ if (type->Is(other) && !type->InUnion(result, old_size)) {
+ result->Set(current_size++, type);
+ }
}
return current_size;
}
// Intersection is O(1) on simple bit unions, but O(n*m) on structured unions.
-// TODO(rossberg): Should we use object sets somehow? Is it worth it?
template<class Config>
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
TypeHandle type1, TypeHandle type2, Region* region) {
// Fast case: bit sets.
if (type1->IsBitset() && type2->IsBitset()) {
- return Config::from_bitset(type1->AsBitset() & type2->AsBitset(), region);
+ return BitsetType::New(type1->AsBitset() & type2->AsBitset(), region);
}
// Fast case: top or bottom types.
- if (type1->IsNone()) return type1;
- if (type2->IsNone()) return type2;
- if (type1->IsAny()) return type2;
- if (type2->IsAny()) return type1;
+ if (type1->IsNone() || type2->IsAny()) return type1;
+ if (type2->IsNone() || type1->IsAny()) return type2;
// Semi-fast case: Unioned objects are neither involved nor produced.
if (!(type1->IsUnion() || type2->IsUnion())) {
@@ -514,19 +570,19 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
// Slow case: may need to produce a Unioned object.
int size = 0;
if (!type1->IsBitset()) {
- size = (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 2);
+ size += (type1->IsUnion() ? type1->AsUnion()->Length() : 1);
}
if (!type2->IsBitset()) {
- int size2 = (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 2);
- size = (size == 0 ? size2 : Min(size, size2));
+ size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1);
}
- ASSERT(size >= 2);
- UnionedHandle unioned = Config::union_create(size, region);
- size = 0;
+ int bitset = type1->BitsetGlb() & type2->BitsetGlb();
+ if (bitset != BitsetType::kNone) ++size;
+ ASSERT(size >= 1);
- int bitset = type1->GlbBitset() & type2->GlbBitset();
- if (bitset != kNone) {
- Config::union_set(unioned, size++, Config::from_bitset(bitset, region));
+ UnionHandle unioned = UnionType::New(size, region);
+ size = 0;
+ if (bitset != BitsetType::kNone) {
+ unioned->Set(size++, BitsetType::New(bitset, region));
}
size = ExtendIntersection(unioned, type1, type2, size);
size = ExtendIntersection(unioned, type2, type1, size);
@@ -534,10 +590,10 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
if (size == 0) {
return None(region);
} else if (size == 1) {
- return Config::union_get(unioned, 0);
+ return unioned->Get(0);
} else {
- Config::union_shrink(unioned, size);
- return Config::from_union(unioned);
+ unioned->Shrink(size);
+ return unioned;
}
}
@@ -547,27 +603,41 @@ template<class OtherType>
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert(
typename OtherType::TypeHandle type, Region* region) {
if (type->IsBitset()) {
- return Config::from_bitset(type->AsBitset(), region);
+ return BitsetType::New(type->AsBitset(), region);
} else if (type->IsClass()) {
- return Config::from_class(type->AsClass(), type->LubBitset(), region);
+ return ClassType::New(type->AsClass()->Map(), region);
} else if (type->IsConstant()) {
- return Config::from_constant(type->AsConstant(), type->LubBitset(), region);
- } else {
- ASSERT(type->IsUnion());
- typename OtherType::UnionedHandle unioned = type->AsUnion();
- int length = OtherType::UnionLength(unioned);
- UnionedHandle new_unioned = Config::union_create(length, region);
+ return ConstantType::New(type->AsConstant()->Value(), region);
+ } else if (type->IsUnion()) {
+ int length = type->AsUnion()->Length();
+ UnionHandle unioned = UnionType::New(length, region);
for (int i = 0; i < length; ++i) {
- Config::union_set(new_unioned, i,
- Convert<OtherType>(OtherType::UnionGet(unioned, i), region));
+ unioned->Set(i, Convert<OtherType>(type->AsUnion()->Get(i), region));
}
- return Config::from_union(new_unioned);
+ return unioned;
+ } else if (type->IsArray()) {
+ return ArrayType::New(
+ Convert<OtherType>(type->AsArray()->Element(), region), region);
+ } else if (type->IsFunction()) {
+ FunctionHandle function = FunctionType::New(
+ Convert<OtherType>(type->AsFunction()->Result(), region),
+ Convert<OtherType>(type->AsFunction()->Receiver(), region),
+ type->AsFunction()->Arity(), region);
+ for (int i = 0; i < function->Arity(); ++i) {
+ function->InitParameter(i,
+ Convert<OtherType>(type->AsFunction()->Parameter(i), region));
+ }
+ return function;
+ } else {
+ UNREACHABLE();
+ return None(region);
}
}
// TODO(rossberg): this does not belong here.
Representation Representation::FromType(Type* type) {
+ DisallowHeapAllocation no_allocation;
if (type->Is(Type::None())) return Representation::None();
if (type->Is(Type::SignedSmall())) return Representation::Smi();
if (type->Is(Type::Signed32())) return Representation::Integer32();
@@ -576,7 +646,6 @@ Representation Representation::FromType(Type* type) {
}
-#ifdef OBJECT_PRINT
template<class Config>
void TypeImpl<Config>::TypePrint(PrintDimension dim) {
TypePrint(stdout, dim);
@@ -586,7 +655,7 @@ void TypeImpl<Config>::TypePrint(PrintDimension dim) {
template<class Config>
-const char* TypeImpl<Config>::bitset_name(int bitset) {
+const char* TypeImpl<Config>::BitsetType::Name(int bitset) {
switch (bitset) {
case kAny & kRepresentation: return "Any";
#define PRINT_COMPOSED_TYPE(type, value) \
@@ -606,8 +675,9 @@ const char* TypeImpl<Config>::bitset_name(int bitset) {
template<class Config>
-void TypeImpl<Config>::BitsetTypePrint(FILE* out, int bitset) {
- const char* name = bitset_name(bitset);
+void TypeImpl<Config>::BitsetType::BitsetTypePrint(FILE* out, int bitset) {
+ DisallowHeapAllocation no_allocation;
+ const char* name = Name(bitset);
if (name != NULL) {
PrintF(out, "%s", name);
} else {
@@ -628,7 +698,7 @@ void TypeImpl<Config>::BitsetTypePrint(FILE* out, int bitset) {
if ((bitset & subset) == subset) {
if (!is_first) PrintF(out, " | ");
is_first = false;
- PrintF(out, "%s", bitset_name(subset));
+ PrintF(out, "%s", Name(subset));
bitset -= subset;
}
}
@@ -640,41 +710,60 @@ void TypeImpl<Config>::BitsetTypePrint(FILE* out, int bitset) {
template<class Config>
void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) {
+ DisallowHeapAllocation no_allocation;
if (this->IsBitset()) {
int bitset = this->AsBitset();
switch (dim) {
case BOTH_DIMS:
- BitsetTypePrint(out, bitset & kSemantic);
- PrintF("/");
- BitsetTypePrint(out, bitset & kRepresentation);
+ BitsetType::BitsetTypePrint(out, bitset & BitsetType::kSemantic);
+ PrintF(out, "/");
+ BitsetType::BitsetTypePrint(out, bitset & BitsetType::kRepresentation);
break;
case SEMANTIC_DIM:
- BitsetTypePrint(out, bitset & kSemantic);
+ BitsetType::BitsetTypePrint(out, bitset & BitsetType::kSemantic);
break;
case REPRESENTATION_DIM:
- BitsetTypePrint(out, bitset & kRepresentation);
+ BitsetType::BitsetTypePrint(out, bitset & BitsetType::kRepresentation);
break;
}
} else if (this->IsConstant()) {
- PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant()));
- Config::from_bitset(this->LubBitset())->TypePrint(out);
- PrintF(")");
+ PrintF(out, "Constant(%p : ",
+ static_cast<void*>(*this->AsConstant()->Value()));
+ BitsetType::New(BitsetType::Lub(this))->TypePrint(out, dim);
+ PrintF(out, ")");
} else if (this->IsClass()) {
- PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass()));
- Config::from_bitset(this->LubBitset())->TypePrint(out);
- PrintF(")");
+ PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass()->Map()));
+ BitsetType::New(BitsetType::Lub(this))->TypePrint(out, dim);
+ PrintF(out, ")");
} else if (this->IsUnion()) {
PrintF(out, "(");
- UnionedHandle unioned = this->AsUnion();
- for (int i = 0; i < Config::union_length(unioned); ++i) {
- TypeHandle type_i = Config::union_get(unioned, i);
+ UnionHandle unioned = handle(this->AsUnion());
+ for (int i = 0; i < unioned->Length(); ++i) {
+ TypeHandle type_i = unioned->Get(i);
if (i > 0) PrintF(out, " | ");
- type_i->TypePrint(out);
+ type_i->TypePrint(out, dim);
}
PrintF(out, ")");
+ } else if (this->IsArray()) {
+ PrintF(out, "[");
+ AsArray()->Element()->TypePrint(out, dim);
+ PrintF(out, "]");
+ } else if (this->IsFunction()) {
+ if (!this->AsFunction()->Receiver()->IsAny()) {
+ this->AsFunction()->Receiver()->TypePrint(out, dim);
+ PrintF(out, ".");
+ }
+ PrintF(out, "(");
+ for (int i = 0; i < this->AsFunction()->Arity(); ++i) {
+ if (i > 0) PrintF(out, ", ");
+ this->AsFunction()->Parameter(i)->TypePrint(out, dim);
+ }
+ PrintF(out, ")->");
+ this->AsFunction()->Result()->TypePrint(out, dim);
+ } else {
+ UNREACHABLE();
}
}
-#endif
template class TypeImpl<ZoneTypeConfig>;
@@ -692,5 +781,4 @@ template TypeImpl<HeapTypeConfig>::TypeHandle
TypeImpl<HeapTypeConfig>::Convert<Type>(
TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*);
-
} } // namespace v8::internal
diff --git a/deps/v8/src/types.h b/deps/v8/src/types.h
index 4569d131b1..5ca3a81452 100644
--- a/deps/v8/src/types.h
+++ b/deps/v8/src/types.h
@@ -1,41 +1,17 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_TYPES_H_
#define V8_TYPES_H_
-#include "v8.h"
-
-#include "objects.h"
+#include "handles.h"
namespace v8 {
namespace internal {
-
+// SUMMARY
+//
// A simple type system for compiler-internal use. It is based entirely on
// union types, and all subtyping hence amounts to set inclusion. Besides the
// obvious primitive types and some predefined unions, the type language also
@@ -45,12 +21,13 @@ namespace internal {
// Types consist of two dimensions: semantic (value range) and representation.
// Both are related through subtyping.
//
+// SEMANTIC DIMENSION
+//
// The following equations and inequations hold for the semantic axis:
//
// None <= T
// T <= Any
//
-// Oddball = Boolean \/ Null \/ Undefined
// Number = Signed32 \/ Unsigned32 \/ Double
// Smi <= Signed32
// Name = String \/ Symbol
@@ -66,11 +43,19 @@ namespace internal {
//
// Class(map) < T iff instance_type(map) < T
// Constant(x) < T iff instance_type(map(x)) < T
+// Array(T) < Array
+// Function(R, S, T0, T1, ...) < Function
//
+// Both structural Array and Function types are invariant in all parameters.
+// Relaxing this would make Union and Intersect operations more involved.
// Note that Constant(x) < Class(map(x)) does _not_ hold, since x's map can
// change! (Its instance type cannot, however.)
// TODO(rossberg): the latter is not currently true for proxies, because of fix,
// but will hold once we implement direct proxies.
+// However, we also define a 'temporal' variant of the subtyping relation that
+// considers the _current_ state only, i.e., Constant(x) <_now Class(map(x)).
+//
+// REPRESENTATIONAL DIMENSION
//
// For the representation axis, the following holds:
//
@@ -96,6 +81,8 @@ namespace internal {
// SignedSmall /\ TaggedInt (a 'smi')
// Number /\ TaggedPtr (a heap number)
//
+// PREDICATES
+//
// There are two main functions for testing types:
//
// T1->Is(T2) -- tests whether T1 is included in T2 (i.e., T1 <= T2)
@@ -109,7 +96,23 @@ namespace internal {
// lattice. That is intentional. It should always be possible to refine the
// lattice (e.g., splitting up number types further) without invalidating any
// existing assumptions or tests.
-// Consequently, do not use pointer equality for type tests, always use Is!
+// Consequently, do not normally use Equals for type tests, always use Is!
+//
+// The NowIs operator implements state-sensitive subtying, as described above.
+// Any compilation decision based on such temporary properties requires runtime
+// guarding!
+//
+// PROPERTIES
+//
+// Various formal properties hold for constructors, operators, and predicates
+// over types. For example, constructors are injective, subtyping is a complete
+// partial order, union and intersection satisfy the usual algebraic properties.
+//
+// See test/cctest/test-types.cc for a comprehensive executable specification,
+// especially with respect to the properties of the more exotic 'temporal'
+// constructors and predicates (those prefixed 'Now').
+//
+// IMPLEMENTATION
//
// Internally, all 'primitive' types, and their unions, are represented as
// bitsets. Class is a heap pointer to the respective map. Only Constant's, or
@@ -168,7 +171,6 @@ namespace internal {
V(Proxy, 1 << 15 | REPRESENTATION(kTaggedPtr)) \
V(Internal, 1 << 16 | REPRESENTATION(kTagged | kUntagged)) \
\
- V(Oddball, kBoolean | kNull | kUndefined) \
V(Signed32, kSignedSmall | kOtherSigned32) \
V(Number, kSigned32 | kUnsigned32 | kFloat) \
V(String, kInternalizedString | kOtherString) \
@@ -180,8 +182,9 @@ namespace internal {
V(Detectable, kDetectableReceiver | kNumber | kName) \
V(Object, kDetectableObject | kUndetectable) \
V(Receiver, kObject | kProxy) \
- V(NonNumber, kOddball | kName | kReceiver | kInternal) \
- V(Any, kNumber | kNonNumber)
+ V(NonNumber, kBoolean | kName | kNull | kReceiver | \
+ kUndefined | kInternal) \
+ V(Any, -1)
#define BITSET_TYPE_LIST(V) \
MASK_BITSET_TYPE_LIST(V) \
@@ -190,103 +193,152 @@ namespace internal {
// struct Config {
+// typedef TypeImpl<Config> Type;
// typedef Base;
-// typedef Unioned;
+// typedef Struct;
// typedef Region;
// template<class> struct Handle { typedef type; } // No template typedefs...
-// static Handle<Type>::type handle(Type* type); // !is_bitset(type)
+// template<class T> static Handle<T>::type handle(T* t); // !is_bitset(t)
+// template<class T> static Handle<T>::type cast(Handle<Type>::type);
// static bool is_bitset(Type*);
// static bool is_class(Type*);
// static bool is_constant(Type*);
-// static bool is_union(Type*);
+// static bool is_struct(Type*, int tag);
// static int as_bitset(Type*);
// static i::Handle<i::Map> as_class(Type*);
// static i::Handle<i::Object> as_constant(Type*);
-// static Handle<Unioned>::type as_union(Type*);
+// static Handle<Struct>::type as_struct(Type*);
// static Type* from_bitset(int bitset);
// static Handle<Type>::type from_bitset(int bitset, Region*);
// static Handle<Type>::type from_class(i::Handle<Map>, int lub, Region*);
// static Handle<Type>::type from_constant(i::Handle<Object>, int, Region*);
-// static Handle<Type>::type from_union(Handle<Unioned>::type);
-// static Handle<Unioned>::type union_create(int size, Region*);
-// static void union_shrink(Handle<Unioned>::type, int size);
-// static Handle<Type>::type union_get(Handle<Unioned>::type, int);
-// static void union_set(Handle<Unioned>::type, int, Handle<Type>::type);
-// static int union_length(Handle<Unioned>::type);
+// static Handle<Type>::type from_struct(Handle<Struct>::type, int tag);
+// static Handle<Struct>::type struct_create(int tag, int length, Region*);
+// static void struct_shrink(Handle<Struct>::type, int length);
+// static int struct_tag(Handle<Struct>::type);
+// static int struct_length(Handle<Struct>::type);
+// static Handle<Type>::type struct_get(Handle<Struct>::type, int);
+// static void struct_set(Handle<Struct>::type, int, Handle<Type>::type);
// static int lub_bitset(Type*);
// }
template<class Config>
class TypeImpl : public Config::Base {
public:
+ class BitsetType; // Internal
+ class StructuralType; // Internal
+ class UnionType; // Internal
+
+ class ClassType;
+ class ConstantType;
+ class ArrayType;
+ class FunctionType;
+
typedef typename Config::template Handle<TypeImpl>::type TypeHandle;
+ typedef typename Config::template Handle<ClassType>::type ClassHandle;
+ typedef typename Config::template Handle<ConstantType>::type ConstantHandle;
+ typedef typename Config::template Handle<ArrayType>::type ArrayHandle;
+ typedef typename Config::template Handle<FunctionType>::type FunctionHandle;
+ typedef typename Config::template Handle<UnionType>::type UnionHandle;
typedef typename Config::Region Region;
- #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
- static TypeImpl* type() { return Config::from_bitset(k##type); } \
- static TypeHandle type(Region* region) { \
- return Config::from_bitset(k##type, region); \
+ #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
+ static TypeImpl* type() { return BitsetType::New(BitsetType::k##type); } \
+ static TypeHandle type(Region* region) { \
+ return BitsetType::New(BitsetType::k##type, region); \
}
BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
#undef DEFINE_TYPE_CONSTRUCTOR
static TypeHandle Class(i::Handle<i::Map> map, Region* region) {
- return Config::from_class(map, LubBitset(*map), region);
+ return ClassType::New(map, region);
}
static TypeHandle Constant(i::Handle<i::Object> value, Region* region) {
- return Config::from_constant(value, LubBitset(*value), region);
+ return ConstantType::New(value, region);
+ }
+ static TypeHandle Array(TypeHandle element, Region* region) {
+ return ArrayType::New(element, region);
+ }
+ static FunctionHandle Function(
+ TypeHandle result, TypeHandle receiver, int arity, Region* region) {
+ return FunctionType::New(result, receiver, arity, region);
+ }
+ static TypeHandle Function(TypeHandle result, Region* region) {
+ return Function(result, Any(region), 0, region);
+ }
+ static TypeHandle Function(
+ TypeHandle result, TypeHandle param0, Region* region) {
+ FunctionHandle function = Function(result, Any(region), 1, region);
+ function->InitParameter(0, param0);
+ return function;
+ }
+ static TypeHandle Function(
+ TypeHandle result, TypeHandle param0, TypeHandle param1, Region* region) {
+ FunctionHandle function = Function(result, Any(region), 2, region);
+ function->InitParameter(0, param0);
+ function->InitParameter(1, param1);
+ return function;
}
static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg);
static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg);
+ static TypeHandle Of(i::Object* value, Region* region) {
+ return Config::from_bitset(BitsetType::Lub(value), region);
+ }
static TypeHandle Of(i::Handle<i::Object> value, Region* region) {
- return Config::from_bitset(LubBitset(*value), region);
+ return Of(*value, region);
+ }
+
+ bool IsInhabited() {
+ return !this->IsBitset() || BitsetType::IsInhabited(this->AsBitset());
}
bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); }
template<class TypeHandle>
bool Is(TypeHandle that) { return this->Is(*that); }
+
bool Maybe(TypeImpl* that);
template<class TypeHandle>
bool Maybe(TypeHandle that) { return this->Maybe(*that); }
+ bool Equals(TypeImpl* that) { return this->Is(that) && that->Is(this); }
+ template<class TypeHandle>
+ bool Equals(TypeHandle that) { return this->Equals(*that); }
+
+ // Equivalent to Constant(value)->Is(this), but avoiding allocation.
+ bool Contains(i::Object* val);
+ bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); }
+
// State-dependent versions of Of and Is that consider subtyping between
// a constant and its map class.
- static TypeHandle OfCurrently(i::Handle<i::Object> value, Region* region);
- bool IsCurrently(TypeImpl* that);
+ static TypeHandle NowOf(i::Object* value, Region* region);
+ static TypeHandle NowOf(i::Handle<i::Object> value, Region* region) {
+ return NowOf(*value, region);
+ }
+ bool NowIs(TypeImpl* that);
template<class TypeHandle>
- bool IsCurrently(TypeHandle that) { return this->IsCurrently(*that); }
+ bool NowIs(TypeHandle that) { return this->NowIs(*that); }
+ inline bool NowContains(i::Object* val);
+ bool NowContains(i::Handle<i::Object> val) { return this->NowContains(*val); }
+
+ bool NowStable();
bool IsClass() { return Config::is_class(this); }
bool IsConstant() { return Config::is_constant(this); }
- i::Handle<i::Map> AsClass() { return Config::as_class(this); }
- i::Handle<i::Object> AsConstant() { return Config::as_constant(this); }
+ bool IsArray() { return Config::is_struct(this, StructuralType::kArrayTag); }
+ bool IsFunction() {
+ return Config::is_struct(this, StructuralType::kFunctionTag);
+ }
+
+ ClassType* AsClass() { return ClassType::cast(this); }
+ ConstantType* AsConstant() { return ConstantType::cast(this); }
+ ArrayType* AsArray() { return ArrayType::cast(this); }
+ FunctionType* AsFunction() { return FunctionType::cast(this); }
int NumClasses();
int NumConstants();
- template<class T>
- class Iterator {
- public:
- bool Done() const { return index_ < 0; }
- i::Handle<T> Current();
- void Advance();
-
- private:
- template<class> friend class TypeImpl;
-
- Iterator() : index_(-1) {}
- explicit Iterator(TypeHandle type) : type_(type), index_(-1) {
- Advance();
- }
-
- inline bool matches(TypeHandle type);
- inline TypeHandle get_type();
-
- TypeHandle type_;
- int index_;
- };
-
+ template<class T> class Iterator;
Iterator<i::Map> Classes() {
if (this->IsBitset()) return Iterator<i::Map>();
return Iterator<i::Map>(Config::handle(this));
@@ -296,32 +348,53 @@ class TypeImpl : public Config::Base {
return Iterator<i::Object>(Config::handle(this));
}
- static TypeImpl* cast(typename Config::Base* object) {
- TypeImpl* t = static_cast<TypeImpl*>(object);
- ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsUnion());
- return t;
- }
+ static inline TypeImpl* cast(typename Config::Base* object);
template<class OtherTypeImpl>
static TypeHandle Convert(
typename OtherTypeImpl::TypeHandle type, Region* region);
-#ifdef OBJECT_PRINT
enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM };
void TypePrint(PrintDimension = BOTH_DIMS);
void TypePrint(FILE* out, PrintDimension = BOTH_DIMS);
-#endif
- private:
+ protected:
template<class> friend class Iterator;
template<class> friend class TypeImpl;
- // A union is a fixed array containing types. Invariants:
- // - its length is at least 2
- // - at most one field is a bitset, and it must go into index 0
- // - no field is a union
- typedef typename Config::Unioned Unioned;
- typedef typename Config::template Handle<Unioned>::type UnionedHandle;
+ template<class T>
+ static typename Config::template Handle<T>::type handle(T* type) {
+ return Config::handle(type);
+ }
+
+ bool IsNone() { return this == None(); }
+ bool IsAny() { return this == Any(); }
+ bool IsBitset() { return Config::is_bitset(this); }
+ bool IsUnion() { return Config::is_struct(this, StructuralType::kUnionTag); }
+
+ int AsBitset() {
+ ASSERT(this->IsBitset());
+ return static_cast<BitsetType*>(this)->Bitset();
+ }
+ UnionType* AsUnion() { return UnionType::cast(this); }
+
+ bool SlowIs(TypeImpl* that);
+
+ bool InUnion(UnionHandle unioned, int current_size);
+ static int ExtendUnion(
+ UnionHandle unioned, TypeHandle t, int current_size);
+ static int ExtendIntersection(
+ UnionHandle unioned, TypeHandle t, TypeHandle other, int current_size);
+
+ int BitsetGlb() { return BitsetType::Glb(this); }
+ int BitsetLub() { return BitsetType::Lub(this); }
+};
+
+
+template<class Config>
+class TypeImpl<Config>::BitsetType : public TypeImpl<Config> {
+ private:
+ friend class TypeImpl<Config>;
enum {
#define DECLARE_TYPE(type, value) k##type = (value),
@@ -330,260 +403,271 @@ class TypeImpl : public Config::Base {
kUnusedEOL = 0
};
- bool IsNone() { return this == None(); }
- bool IsAny() { return this == Any(); }
- bool IsBitset() { return Config::is_bitset(this); }
- bool IsUnion() { return Config::is_union(this); }
- int AsBitset() { return Config::as_bitset(this); }
- UnionedHandle AsUnion() { return Config::as_union(this); }
+ int Bitset() { return Config::as_bitset(this); }
- static int UnionLength(UnionedHandle unioned) {
- return Config::union_length(unioned);
+ static BitsetType* New(int bitset) {
+ return static_cast<BitsetType*>(Config::from_bitset(bitset));
}
- static TypeHandle UnionGet(UnionedHandle unioned, int i) {
- return Config::union_get(unioned, i);
+ static TypeHandle New(int bitset, Region* region) {
+ return Config::from_bitset(bitset, region);
}
- bool SlowIs(TypeImpl* that);
-
static bool IsInhabited(int bitset) {
return (bitset & kRepresentation) && (bitset & kSemantic);
}
- int LubBitset(); // least upper bound that's a bitset
- int GlbBitset(); // greatest lower bound that's a bitset
-
- static int LubBitset(i::Object* value);
- static int LubBitset(i::Map* map);
-
- bool InUnion(UnionedHandle unioned, int current_size);
- static int ExtendUnion(
- UnionedHandle unioned, TypeHandle t, int current_size);
- static int ExtendIntersection(
- UnionedHandle unioned, TypeHandle t, TypeHandle other, int current_size);
+ static int Glb(TypeImpl* type); // greatest lower bound that's a bitset
+ static int Lub(TypeImpl* type); // least upper bound that's a bitset
+ static int Lub(i::Object* value);
+ static int Lub(i::Map* map);
-#ifdef OBJECT_PRINT
- static const char* bitset_name(int bitset);
+ static const char* Name(int bitset);
static void BitsetTypePrint(FILE* out, int bitset);
-#endif
};
-// Zone-allocated types are either (odd) integers to represent bitsets, or
-// (even) pointers to zone lists for everything else. The first slot of every
-// list is an explicit tag value to distinguish representation.
-struct ZoneTypeConfig {
- private:
- typedef i::ZoneList<void*> Tagged;
+// Internal
+// A structured type contains a tag and a variable number of type fields.
+template<class Config>
+class TypeImpl<Config>::StructuralType : public TypeImpl<Config> {
+ protected:
+ template<class> friend class TypeImpl;
+ friend struct ZoneTypeConfig; // For tags.
+ friend struct HeapTypeConfig;
enum Tag {
kClassTag,
kConstantTag,
+ kArrayTag,
+ kFunctionTag,
kUnionTag
};
- static Tagged* tagged_create(Tag tag, int size, Zone* zone) {
- Tagged* tagged = new(zone) Tagged(size + 1, zone);
- tagged->Add(reinterpret_cast<void*>(tag), zone);
- tagged->AddBlock(NULL, size, zone);
- return tagged;
+ int Length() {
+ return Config::struct_length(Config::as_struct(this));
}
- static void tagged_shrink(Tagged* tagged, int size) {
- tagged->Rewind(size + 1);
+ TypeHandle Get(int i) {
+ return Config::struct_get(Config::as_struct(this), i);
}
- static Tag tagged_tag(Tagged* tagged) {
- return static_cast<Tag>(reinterpret_cast<intptr_t>(tagged->at(0)));
+ void Set(int i, TypeHandle type) {
+ Config::struct_set(Config::as_struct(this), i, type);
}
- template<class T>
- static T tagged_get(Tagged* tagged, int i) {
- return reinterpret_cast<T>(tagged->at(i + 1));
- }
- template<class T>
- static void tagged_set(Tagged* tagged, int i, T value) {
- tagged->at(i + 1) = reinterpret_cast<void*>(value);
+ void Shrink(int length) {
+ Config::struct_shrink(Config::as_struct(this), length);
}
- static int tagged_length(Tagged* tagged) {
- return tagged->length() - 1;
+
+ static TypeHandle New(Tag tag, int length, Region* region) {
+ return Config::from_struct(Config::struct_create(tag, length, region));
}
+};
- public:
- typedef TypeImpl<ZoneTypeConfig> Type;
- class Base {};
- typedef i::ZoneList<Type*> Unioned;
- typedef i::Zone Region;
- template<class T> struct Handle { typedef T* type; };
- static Type* handle(Type* type) { return type; }
+template<class Config>
+class TypeImpl<Config>::ClassType : public TypeImpl<Config> {
+ public:
+ i::Handle<i::Map> Map() { return Config::as_class(this); }
- static bool is(Type* type, Tag tag) {
- return is_tagged(type) && tagged_tag(as_tagged(type)) == tag;
+ static ClassHandle New(i::Handle<i::Map> map, Region* region) {
+ return Config::template cast<ClassType>(
+ Config::from_class(map, BitsetType::Lub(*map), region));
}
- static bool is_bitset(Type* type) {
- return reinterpret_cast<intptr_t>(type) & 1;
- }
- static bool is_tagged(Type* type) { return !is_bitset(type); }
- static bool is_class(Type* type) { return is(type, kClassTag); }
- static bool is_constant(Type* type) { return is(type, kConstantTag); }
- static bool is_union(Type* type) { return is(type, kUnionTag); }
- static bool tagged_is_union(Tagged* tagged) {
- return is(from_tagged(tagged), kUnionTag);
+ static ClassType* cast(TypeImpl* type) {
+ ASSERT(type->IsClass());
+ return static_cast<ClassType*>(type);
}
+};
- static int as_bitset(Type* type) {
- ASSERT(is_bitset(type));
- return static_cast<int>(reinterpret_cast<intptr_t>(type) >> 1);
- }
- static Tagged* as_tagged(Type* type) {
- ASSERT(is_tagged(type));
- return reinterpret_cast<Tagged*>(type);
- }
- static i::Handle<i::Map> as_class(Type* type) {
- ASSERT(is_class(type));
- return i::Handle<i::Map>(tagged_get<i::Map**>(as_tagged(type), 1));
- }
- static i::Handle<i::Object> as_constant(Type* type) {
- ASSERT(is_constant(type));
- return i::Handle<i::Object>(tagged_get<i::Object**>(as_tagged(type), 1));
- }
- static Unioned* as_union(Type* type) {
- ASSERT(is_union(type));
- return tagged_as_union(as_tagged(type));
- }
- static Unioned* tagged_as_union(Tagged* tagged) {
- ASSERT(tagged_is_union(tagged));
- return reinterpret_cast<Unioned*>(tagged);
- }
- static Type* from_bitset(int bitset) {
- return reinterpret_cast<Type*>((bitset << 1) | 1);
- }
- static Type* from_bitset(int bitset, Zone* Zone) {
- return from_bitset(bitset);
- }
- static Type* from_tagged(Tagged* tagged) {
- return reinterpret_cast<Type*>(tagged);
- }
- static Type* from_class(i::Handle<i::Map> map, int lub, Zone* zone) {
- Tagged* tagged = tagged_create(kClassTag, 2, zone);
- tagged_set(tagged, 0, lub);
- tagged_set(tagged, 1, map.location());
- return from_tagged(tagged);
+template<class Config>
+class TypeImpl<Config>::ConstantType : public TypeImpl<Config> {
+ public:
+ i::Handle<i::Object> Value() { return Config::as_constant(this); }
+
+ static ConstantHandle New(i::Handle<i::Object> value, Region* region) {
+ return Config::template cast<ConstantType>(
+ Config::from_constant(value, BitsetType::Lub(*value), region));
}
- static Type* from_constant(i::Handle<i::Object> value, int lub, Zone* zone) {
- Tagged* tagged = tagged_create(kConstantTag, 2, zone);
- tagged_set(tagged, 0, lub);
- tagged_set(tagged, 1, value.location());
- return from_tagged(tagged);
+
+ static ConstantType* cast(TypeImpl* type) {
+ ASSERT(type->IsConstant());
+ return static_cast<ConstantType*>(type);
}
- static Type* from_union(Unioned* unioned) {
- return from_tagged(tagged_from_union(unioned));
+};
+
+
+// Internal
+// A union is a structured type with the following invariants:
+// - its length is at least 2
+// - at most one field is a bitset, and it must go into index 0
+// - no field is a union
+template<class Config>
+class TypeImpl<Config>::UnionType : public StructuralType {
+ public:
+ static UnionHandle New(int length, Region* region) {
+ return Config::template cast<UnionType>(
+ StructuralType::New(StructuralType::kUnionTag, length, region));
}
- static Tagged* tagged_from_union(Unioned* unioned) {
- return reinterpret_cast<Tagged*>(unioned);
+
+ static UnionType* cast(TypeImpl* type) {
+ ASSERT(type->IsUnion());
+ return static_cast<UnionType*>(type);
}
+};
+
+
+template<class Config>
+class TypeImpl<Config>::ArrayType : public StructuralType {
+ public:
+ TypeHandle Element() { return this->Get(0); }
- static Unioned* union_create(int size, Zone* zone) {
- return tagged_as_union(tagged_create(kUnionTag, size, zone));
+ static ArrayHandle New(TypeHandle element, Region* region) {
+ ArrayHandle type = Config::template cast<ArrayType>(
+ StructuralType::New(StructuralType::kArrayTag, 1, region));
+ type->Set(0, element);
+ return type;
}
- static void union_shrink(Unioned* unioned, int size) {
- tagged_shrink(tagged_from_union(unioned), size);
+
+ static ArrayType* cast(TypeImpl* type) {
+ ASSERT(type->IsArray());
+ return static_cast<ArrayType*>(type);
}
- static Type* union_get(Unioned* unioned, int i) {
- Type* type = tagged_get<Type*>(tagged_from_union(unioned), i);
- ASSERT(!is_union(type));
+};
+
+
+template<class Config>
+class TypeImpl<Config>::FunctionType : public StructuralType {
+ public:
+ int Arity() { return this->Length() - 2; }
+ TypeHandle Result() { return this->Get(0); }
+ TypeHandle Receiver() { return this->Get(1); }
+ TypeHandle Parameter(int i) { return this->Get(2 + i); }
+
+ void InitParameter(int i, TypeHandle type) { this->Set(2 + i, type); }
+
+ static FunctionHandle New(
+ TypeHandle result, TypeHandle receiver, int arity, Region* region) {
+ FunctionHandle type = Config::template cast<FunctionType>(
+ StructuralType::New(StructuralType::kFunctionTag, 2 + arity, region));
+ type->Set(0, result);
+ type->Set(1, receiver);
return type;
}
- static void union_set(Unioned* unioned, int i, Type* type) {
- ASSERT(!is_union(type));
- tagged_set(tagged_from_union(unioned), i, type);
- }
- static int union_length(Unioned* unioned) {
- return tagged_length(tagged_from_union(unioned));
+
+ static FunctionType* cast(TypeImpl* type) {
+ ASSERT(type->IsFunction());
+ return static_cast<FunctionType*>(type);
}
- static int lub_bitset(Type* type) {
- ASSERT(is_class(type) || is_constant(type));
- return static_cast<int>(tagged_get<intptr_t>(as_tagged(type), 0));
+};
+
+
+template<class Config> template<class T>
+class TypeImpl<Config>::Iterator {
+ public:
+ bool Done() const { return index_ < 0; }
+ i::Handle<T> Current();
+ void Advance();
+
+ private:
+ template<class> friend class TypeImpl;
+
+ Iterator() : index_(-1) {}
+ explicit Iterator(TypeHandle type) : type_(type), index_(-1) {
+ Advance();
}
+
+ inline bool matches(TypeHandle type);
+ inline TypeHandle get_type();
+
+ TypeHandle type_;
+ int index_;
+};
+
+
+// Zone-allocated types are either (odd) integers to represent bitsets, or
+// (even) pointers to structures for everything else.
+struct ZoneTypeConfig {
+ typedef TypeImpl<ZoneTypeConfig> Type;
+ class Base {};
+ typedef void* Struct;
+ typedef i::Zone Region;
+ template<class T> struct Handle { typedef T* type; };
+
+ template<class T> static inline T* handle(T* type);
+ template<class T> static inline T* cast(Type* type);
+
+ static inline bool is_bitset(Type* type);
+ static inline bool is_class(Type* type);
+ static inline bool is_constant(Type* type);
+ static inline bool is_struct(Type* type, int tag);
+
+ static inline int as_bitset(Type* type);
+ static inline Struct* as_struct(Type* type);
+ static inline i::Handle<i::Map> as_class(Type* type);
+ static inline i::Handle<i::Object> as_constant(Type* type);
+
+ static inline Type* from_bitset(int bitset);
+ static inline Type* from_bitset(int bitset, Zone* zone);
+ static inline Type* from_struct(Struct* structured);
+ static inline Type* from_class(i::Handle<i::Map> map, int lub, Zone* zone);
+ static inline Type* from_constant(
+ i::Handle<i::Object> value, int lub, Zone* zone);
+
+ static inline Struct* struct_create(int tag, int length, Zone* zone);
+ static inline void struct_shrink(Struct* structured, int length);
+ static inline int struct_tag(Struct* structured);
+ static inline int struct_length(Struct* structured);
+ static inline Type* struct_get(Struct* structured, int i);
+ static inline void struct_set(Struct* structured, int i, Type* type);
+
+ static inline int lub_bitset(Type* type);
};
+typedef TypeImpl<ZoneTypeConfig> Type;
+
// Heap-allocated types are either smis for bitsets, maps for classes, boxes for
// constants, or fixed arrays for unions.
struct HeapTypeConfig {
typedef TypeImpl<HeapTypeConfig> Type;
typedef i::Object Base;
- typedef i::FixedArray Unioned;
+ typedef i::FixedArray Struct;
typedef i::Isolate Region;
template<class T> struct Handle { typedef i::Handle<T> type; };
- static i::Handle<Type> handle(Type* type) {
- return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
- }
-
- static bool is_bitset(Type* type) { return type->IsSmi(); }
- static bool is_class(Type* type) { return type->IsMap(); }
- static bool is_constant(Type* type) { return type->IsBox(); }
- static bool is_union(Type* type) { return type->IsFixedArray(); }
-
- static int as_bitset(Type* type) {
- return Smi::cast(type)->value();
- }
- static i::Handle<i::Map> as_class(Type* type) {
- return i::handle(i::Map::cast(type));
- }
- static i::Handle<i::Object> as_constant(Type* type) {
- i::Box* box = i::Box::cast(type);
- return i::handle(box->value(), box->GetIsolate());
- }
- static i::Handle<Unioned> as_union(Type* type) {
- return i::handle(i::FixedArray::cast(type));
- }
-
- static Type* from_bitset(int bitset) {
- return Type::cast(i::Smi::FromInt(bitset));
- }
- static i::Handle<Type> from_bitset(int bitset, Isolate* isolate) {
- return i::handle(from_bitset(bitset), isolate);
- }
- static i::Handle<Type> from_class(
- i::Handle<i::Map> map, int lub, Isolate* isolate) {
- return i::Handle<Type>::cast(i::Handle<Object>::cast(map));
- }
- static i::Handle<Type> from_constant(
- i::Handle<i::Object> value, int lub, Isolate* isolate) {
- i::Handle<Box> box = isolate->factory()->NewBox(value);
- return i::Handle<Type>::cast(i::Handle<Object>::cast(box));
- }
- static i::Handle<Type> from_union(i::Handle<Unioned> unioned) {
- return i::Handle<Type>::cast(i::Handle<Object>::cast(unioned));
- }
-
- static i::Handle<Unioned> union_create(int size, Isolate* isolate) {
- return isolate->factory()->NewFixedArray(size);
- }
- static void union_shrink(i::Handle<Unioned> unioned, int size) {
- unioned->Shrink(size);
- }
- static i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i) {
- Type* type = static_cast<Type*>(unioned->get(i));
- ASSERT(!is_union(type));
- return i::handle(type, unioned->GetIsolate());
- }
- static void union_set(
- i::Handle<Unioned> unioned, int i, i::Handle<Type> type) {
- ASSERT(!is_union(*type));
- unioned->set(i, *type);
- }
- static int union_length(i::Handle<Unioned> unioned) {
- return unioned->length();
- }
- static int lub_bitset(Type* type) {
- return 0; // kNone, which causes recomputation.
- }
+ template<class T> static inline i::Handle<T> handle(T* type);
+ template<class T> static inline i::Handle<T> cast(i::Handle<Type> type);
+
+ static inline bool is_bitset(Type* type);
+ static inline bool is_class(Type* type);
+ static inline bool is_constant(Type* type);
+ static inline bool is_struct(Type* type, int tag);
+
+ static inline int as_bitset(Type* type);
+ static inline i::Handle<i::Map> as_class(Type* type);
+ static inline i::Handle<i::Object> as_constant(Type* type);
+ static inline i::Handle<Struct> as_struct(Type* type);
+
+ static inline Type* from_bitset(int bitset);
+ static inline i::Handle<Type> from_bitset(int bitset, Isolate* isolate);
+ static inline i::Handle<Type> from_class(
+ i::Handle<i::Map> map, int lub, Isolate* isolate);
+ static inline i::Handle<Type> from_constant(
+ i::Handle<i::Object> value, int lub, Isolate* isolate);
+ static inline i::Handle<Type> from_struct(i::Handle<Struct> structured);
+
+ static inline i::Handle<Struct> struct_create(
+ int tag, int length, Isolate* isolate);
+ static inline void struct_shrink(i::Handle<Struct> structured, int length);
+ static inline int struct_tag(i::Handle<Struct> structured);
+ static inline int struct_length(i::Handle<Struct> structured);
+ static inline i::Handle<Type> struct_get(i::Handle<Struct> structured, int i);
+ static inline void struct_set(
+ i::Handle<Struct> structured, int i, i::Handle<Type> type);
+
+ static inline int lub_bitset(Type* type);
};
-typedef TypeImpl<ZoneTypeConfig> Type;
typedef TypeImpl<HeapTypeConfig> HeapType;
@@ -643,7 +727,6 @@ struct BoundsImpl {
typedef BoundsImpl<ZoneTypeConfig> Bounds;
-
} } // namespace v8::internal
#endif // V8_TYPES_H_
diff --git a/deps/v8/src/typing.cc b/deps/v8/src/typing.cc
index 2a581e293a..434aff3490 100644
--- a/deps/v8/src/typing.cc
+++ b/deps/v8/src/typing.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "typing.h"
@@ -39,8 +16,9 @@ namespace internal {
AstTyper::AstTyper(CompilationInfo* info)
: info_(info),
oracle_(
- Handle<Code>(info->closure()->shared()->code()),
- Handle<Context>(info->closure()->context()->native_context()),
+ handle(info->closure()->shared()->code()),
+ handle(info->closure()->shared()->feedback_vector()),
+ handle(info->closure()->context()->native_context()),
info->zone()),
store_(info->zone()) {
InitializeAstVisitor(info->zone());
@@ -83,7 +61,7 @@ void AstTyper::Run(CompilationInfo* info) {
Effect AstTyper::ObservedOnStack(Object* value) {
- Type* lower = Type::OfCurrently(handle(value, isolate()), zone());
+ Type* lower = Type::NowOf(value, zone());
return Effect(Bounds(lower, Type::Any(zone())));
}
@@ -530,7 +508,7 @@ void AstTyper::VisitCall(Call* expr) {
// Collect type feedback.
RECURSE(Visit(expr->expression()));
if (!expr->expression()->IsProperty() &&
- expr->HasCallFeedbackSlot() &&
+ expr->IsUsingCallFeedbackSlot(isolate()) &&
oracle()->CallIsMonomorphic(expr->CallFeedbackSlot())) {
expr->set_target(oracle()->GetCallTarget(expr->CallFeedbackSlot()));
}
diff --git a/deps/v8/src/typing.h b/deps/v8/src/typing.h
index 0517812ec3..71a63c3090 100644
--- a/deps/v8/src/typing.h
+++ b/deps/v8/src/typing.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_TYPING_H_
#define V8_TYPING_H_
diff --git a/deps/v8/src/unbound-queue-inl.h b/deps/v8/src/unbound-queue-inl.h
index 796ba401d5..7c2e8bc4f4 100644
--- a/deps/v8/src/unbound-queue-inl.h
+++ b/deps/v8/src/unbound-queue-inl.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_UNBOUND_QUEUE_INL_H_
#define V8_UNBOUND_QUEUE_INL_H_
diff --git a/deps/v8/src/unbound-queue.h b/deps/v8/src/unbound-queue.h
index 429e3c673e..35a3ef499f 100644
--- a/deps/v8/src/unbound-queue.h
+++ b/deps/v8/src/unbound-queue.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_UNBOUND_QUEUE_
#define V8_UNBOUND_QUEUE_
diff --git a/deps/v8/src/unicode-inl.h b/deps/v8/src/unicode-inl.h
index 99eca644b7..a0142d2259 100644
--- a/deps/v8/src/unicode-inl.h
+++ b/deps/v8/src/unicode-inl.h
@@ -1,29 +1,6 @@
// Copyright 2007-2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_UNICODE_INL_H_
#define V8_UNICODE_INL_H_
diff --git a/deps/v8/src/unicode.cc b/deps/v8/src/unicode.cc
index 2bef7ab20b..3322110ab2 100644
--- a/deps/v8/src/unicode.cc
+++ b/deps/v8/src/unicode.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
//
// This file was generated at 2014-02-07 15:31:16.733174
diff --git a/deps/v8/src/unicode.h b/deps/v8/src/unicode.h
index 65a9af58fc..ecb5ab4d7d 100644
--- a/deps/v8/src/unicode.h
+++ b/deps/v8/src/unicode.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_UNICODE_H_
#define V8_UNICODE_H_
diff --git a/deps/v8/src/unique.h b/deps/v8/src/unique.h
index 2f6008c5a2..8ed2682901 100644
--- a/deps/v8/src/unique.h
+++ b/deps/v8/src/unique.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_HYDROGEN_UNIQUE_H_
#define V8_HYDROGEN_UNIQUE_H_
@@ -157,6 +134,19 @@ class UniqueSet V8_FINAL : public ZoneObject {
// Constructor. A new set will be empty.
UniqueSet() : size_(0), capacity_(0), array_(NULL) { }
+ // Capacity constructor. A new set will be empty.
+ UniqueSet(int capacity, Zone* zone)
+ : size_(0), capacity_(capacity),
+ array_(zone->NewArray<Unique<T> >(capacity)) {
+ ASSERT(capacity <= kMaxCapacity);
+ }
+
+ // Singleton constructor.
+ UniqueSet(Unique<T> uniq, Zone* zone)
+ : size_(1), capacity_(1), array_(zone->NewArray<Unique<T> >(1)) {
+ array_[0] = uniq;
+ }
+
// Add a new element to this unique set. Mutates this set. O(|this|).
void Add(Unique<T> uniq, Zone* zone) {
ASSERT(uniq.IsInitialized());
@@ -189,7 +179,7 @@ class UniqueSet V8_FINAL : public ZoneObject {
}
// Compare this set against another set. O(|this|).
- bool Equals(UniqueSet<T>* that) const {
+ bool Equals(const UniqueSet<T>* that) const {
if (that->size_ != this->size_) return false;
for (int i = 0; i < this->size_; i++) {
if (this->array_[i] != that->array_[i]) return false;
@@ -200,15 +190,18 @@ class UniqueSet V8_FINAL : public ZoneObject {
// Check whether this set contains the given element. O(|this|)
// TODO(titzer): use binary search for large sets to make this O(log|this|)
template <typename U>
- bool Contains(Unique<U> elem) const {
- for (int i = 0; i < size_; i++) {
- if (this->array_[i] == elem) return true;
+ bool Contains(const Unique<U> elem) const {
+ for (int i = 0; i < this->size_; ++i) {
+ Unique<T> cand = this->array_[i];
+ if (cand.raw_address_ >= elem.raw_address_) {
+ return cand.raw_address_ == elem.raw_address_;
+ }
}
return false;
}
// Check if this set is a subset of the given set. O(|this| + |that|).
- bool IsSubset(UniqueSet<T>* that) const {
+ bool IsSubset(const UniqueSet<T>* that) const {
if (that->size_ < this->size_) return false;
int j = 0;
for (int i = 0; i < this->size_; i++) {
@@ -224,11 +217,11 @@ class UniqueSet V8_FINAL : public ZoneObject {
// Returns a new set representing the intersection of this set and the other.
// O(|this| + |that|).
- UniqueSet<T>* Intersect(UniqueSet<T>* that, Zone* zone) const {
+ UniqueSet<T>* Intersect(const UniqueSet<T>* that, Zone* zone) const {
if (that->size_ == 0 || this->size_ == 0) return new(zone) UniqueSet<T>();
- UniqueSet<T>* out = new(zone) UniqueSet<T>();
- out->Grow(Min(this->size_, that->size_), zone);
+ UniqueSet<T>* out = new(zone) UniqueSet<T>(
+ Min(this->size_, that->size_), zone);
int i = 0, j = 0, k = 0;
while (i < this->size_ && j < that->size_) {
@@ -251,12 +244,12 @@ class UniqueSet V8_FINAL : public ZoneObject {
// Returns a new set representing the union of this set and the other.
// O(|this| + |that|).
- UniqueSet<T>* Union(UniqueSet<T>* that, Zone* zone) const {
+ UniqueSet<T>* Union(const UniqueSet<T>* that, Zone* zone) const {
if (that->size_ == 0) return this->Copy(zone);
if (this->size_ == 0) return that->Copy(zone);
- UniqueSet<T>* out = new(zone) UniqueSet<T>();
- out->Grow(this->size_ + that->size_, zone);
+ UniqueSet<T>* out = new(zone) UniqueSet<T>(
+ this->size_ + that->size_, zone);
int i = 0, j = 0, k = 0;
while (i < this->size_ && j < that->size_) {
@@ -284,10 +277,8 @@ class UniqueSet V8_FINAL : public ZoneObject {
// Makes an exact copy of this set. O(|this|).
UniqueSet<T>* Copy(Zone* zone) const {
- UniqueSet<T>* copy = new(zone) UniqueSet<T>();
+ UniqueSet<T>* copy = new(zone) UniqueSet<T>(this->size_, zone);
copy->size_ = this->size_;
- copy->capacity_ = this->size_;
- copy->array_ = zone->NewArray<Unique<T> >(this->size_);
memcpy(copy->array_, this->array_, this->size_ * sizeof(Unique<T>));
return copy;
}
diff --git a/deps/v8/src/uri.h b/deps/v8/src/uri.h
index 1e73ddd3d2..6b76525fea 100644
--- a/deps/v8/src/uri.h
+++ b/deps/v8/src/uri.h
@@ -1,38 +1,15 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_URI_H_
#define V8_URI_H_
#include "v8.h"
+#include "conversions.h"
#include "string-search.h"
-#include "v8utils.h"
-#include "v8conversions.h"
+#include "utils.h"
namespace v8 {
namespace internal {
@@ -61,13 +38,14 @@ Vector<const uc16> GetCharVector(Handle<String> string) {
class URIUnescape : public AllStatic {
public:
template<typename Char>
- static Handle<String> Unescape(Isolate* isolate, Handle<String> source);
+ MUST_USE_RESULT static MaybeHandle<String> Unescape(Isolate* isolate,
+ Handle<String> source);
private:
static const signed char kHexValue['g'];
template<typename Char>
- static Handle<String> UnescapeSlow(
+ MUST_USE_RESULT static MaybeHandle<String> UnescapeSlow(
Isolate* isolate, Handle<String> string, int start_index);
static INLINE(int TwoDigitHex(uint16_t character1, uint16_t character2));
@@ -91,7 +69,8 @@ const signed char URIUnescape::kHexValue[] = {
template<typename Char>
-Handle<String> URIUnescape::Unescape(Isolate* isolate, Handle<String> source) {
+MaybeHandle<String> URIUnescape::Unescape(Isolate* isolate,
+ Handle<String> source) {
int index;
{ DisallowHeapAllocation no_allocation;
StringSearch<uint8_t, Char> search(isolate, STATIC_ASCII_VECTOR("%"));
@@ -103,7 +82,7 @@ Handle<String> URIUnescape::Unescape(Isolate* isolate, Handle<String> source) {
template <typename Char>
-Handle<String> URIUnescape::UnescapeSlow(
+MaybeHandle<String> URIUnescape::UnescapeSlow(
Isolate* isolate, Handle<String> string, int start_index) {
bool one_byte = true;
int length = string->length();
@@ -129,9 +108,8 @@ Handle<String> URIUnescape::UnescapeSlow(
Handle<String> second_part;
ASSERT(unescaped_length <= String::kMaxLength);
if (one_byte) {
- Handle<SeqOneByteString> dest =
- isolate->factory()->NewRawOneByteString(unescaped_length);
- ASSERT(!dest.is_null());
+ Handle<SeqOneByteString> dest = isolate->factory()->NewRawOneByteString(
+ unescaped_length).ToHandleChecked();
DisallowHeapAllocation no_allocation;
Vector<const Char> vector = GetCharVector<Char>(string);
for (int i = start_index; i < length; dest_position++) {
@@ -142,9 +120,8 @@ Handle<String> URIUnescape::UnescapeSlow(
}
second_part = dest;
} else {
- Handle<SeqTwoByteString> dest =
- isolate->factory()->NewRawTwoByteString(unescaped_length);
- ASSERT(!dest.is_null());
+ Handle<SeqTwoByteString> dest = isolate->factory()->NewRawTwoByteString(
+ unescaped_length).ToHandleChecked();
DisallowHeapAllocation no_allocation;
Vector<const Char> vector = GetCharVector<Char>(string);
for (int i = start_index; i < length; dest_position++) {
@@ -203,7 +180,8 @@ int URIUnescape::UnescapeChar(Vector<const Char> vector,
class URIEscape : public AllStatic {
public:
template<typename Char>
- static Handle<String> Escape(Isolate* isolate, Handle<String> string);
+ MUST_USE_RESULT static MaybeHandle<String> Escape(Isolate* isolate,
+ Handle<String> string);
private:
static const char kHexChars[17];
@@ -247,7 +225,7 @@ const char URIEscape::kNotEscaped[] = {
template<typename Char>
-Handle<String> URIEscape::Escape(Isolate* isolate, Handle<String> string) {
+MaybeHandle<String> URIEscape::Escape(Isolate* isolate, Handle<String> string) {
ASSERT(string->IsFlat());
int escaped_length = 0;
int length = string->length();
@@ -273,9 +251,11 @@ Handle<String> URIEscape::Escape(Isolate* isolate, Handle<String> string) {
// No length change implies no change. Return original string if no change.
if (escaped_length == length) return string;
- Handle<SeqOneByteString> dest =
- isolate->factory()->NewRawOneByteString(escaped_length);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, dest, Handle<String>());
+ Handle<SeqOneByteString> dest;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, dest,
+ isolate->factory()->NewRawOneByteString(escaped_length),
+ String);
int dest_position = 0;
{ DisallowHeapAllocation no_allocation;
diff --git a/deps/v8/src/uri.js b/deps/v8/src/uri.js
index 4e3f084af2..0e50f0b700 100644
--- a/deps/v8/src/uri.js
+++ b/deps/v8/src/uri.js
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file relies on the fact that the following declaration has been made
// in runtime.js:
diff --git a/deps/v8/src/utils-inl.h b/deps/v8/src/utils-inl.h
index 76a3c104ef..8c89f65f77 100644
--- a/deps/v8/src/utils-inl.h
+++ b/deps/v8/src/utils-inl.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_UTILS_INL_H_
#define V8_UTILS_INL_H_
diff --git a/deps/v8/src/utils.cc b/deps/v8/src/utils.cc
index 6838cb069d..7af30f27b7 100644
--- a/deps/v8/src/utils.cc
+++ b/deps/v8/src/utils.cc
@@ -1,32 +1,12 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <stdarg.h>
-#include "../include/v8stdint.h"
+#include <sys/stat.h>
+
+#include "v8.h"
+
#include "checks.h"
#include "platform.h"
#include "utils.h"
@@ -97,4 +77,241 @@ char* SimpleStringBuilder::Finalize() {
}
+void PrintF(const char* format, ...) {
+ va_list arguments;
+ va_start(arguments, format);
+ OS::VPrint(format, arguments);
+ va_end(arguments);
+}
+
+
+void PrintF(FILE* out, const char* format, ...) {
+ va_list arguments;
+ va_start(arguments, format);
+ OS::VFPrint(out, format, arguments);
+ va_end(arguments);
+}
+
+
+void PrintPID(const char* format, ...) {
+ OS::Print("[%d] ", OS::GetCurrentProcessId());
+ va_list arguments;
+ va_start(arguments, format);
+ OS::VPrint(format, arguments);
+ va_end(arguments);
+}
+
+
+void Flush(FILE* out) {
+ fflush(out);
+}
+
+
+char* ReadLine(const char* prompt) {
+ char* result = NULL;
+ char line_buf[256];
+ int offset = 0;
+ bool keep_going = true;
+ fprintf(stdout, "%s", prompt);
+ fflush(stdout);
+ while (keep_going) {
+ if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
+ // fgets got an error. Just give up.
+ if (result != NULL) {
+ DeleteArray(result);
+ }
+ return NULL;
+ }
+ int len = StrLength(line_buf);
+ if (len > 1 &&
+ line_buf[len - 2] == '\\' &&
+ line_buf[len - 1] == '\n') {
+ // When we read a line that ends with a "\" we remove the escape and
+ // append the remainder.
+ line_buf[len - 2] = '\n';
+ line_buf[len - 1] = 0;
+ len -= 1;
+ } else if ((len > 0) && (line_buf[len - 1] == '\n')) {
+ // Since we read a new line we are done reading the line. This
+ // will exit the loop after copying this buffer into the result.
+ keep_going = false;
+ }
+ if (result == NULL) {
+ // Allocate the initial result and make room for the terminating '\0'
+ result = NewArray<char>(len + 1);
+ } else {
+ // Allocate a new result with enough room for the new addition.
+ int new_len = offset + len + 1;
+ char* new_result = NewArray<char>(new_len);
+ // Copy the existing input into the new array and set the new
+ // array as the result.
+ OS::MemCopy(new_result, result, offset * kCharSize);
+ DeleteArray(result);
+ result = new_result;
+ }
+ // Copy the newly read line into the result.
+ OS::MemCopy(result + offset, line_buf, len * kCharSize);
+ offset += len;
+ }
+ ASSERT(result != NULL);
+ result[offset] = '\0';
+ return result;
+}
+
+
+char* ReadCharsFromFile(FILE* file,
+ int* size,
+ int extra_space,
+ bool verbose,
+ const char* filename) {
+ if (file == NULL || fseek(file, 0, SEEK_END) != 0) {
+ if (verbose) {
+ OS::PrintError("Cannot read from file %s.\n", filename);
+ }
+ return NULL;
+ }
+
+ // Get the size of the file and rewind it.
+ *size = ftell(file);
+ rewind(file);
+
+ char* result = NewArray<char>(*size + extra_space);
+ for (int i = 0; i < *size && feof(file) == 0;) {
+ int read = static_cast<int>(fread(&result[i], 1, *size - i, file));
+ if (read != (*size - i) && ferror(file) != 0) {
+ fclose(file);
+ DeleteArray(result);
+ return NULL;
+ }
+ i += read;
+ }
+ return result;
+}
+
+
+char* ReadCharsFromFile(const char* filename,
+ int* size,
+ int extra_space,
+ bool verbose) {
+ FILE* file = OS::FOpen(filename, "rb");
+ char* result = ReadCharsFromFile(file, size, extra_space, verbose, filename);
+ if (file != NULL) fclose(file);
+ return result;
+}
+
+
+byte* ReadBytes(const char* filename, int* size, bool verbose) {
+ char* chars = ReadCharsFromFile(filename, size, 0, verbose);
+ return reinterpret_cast<byte*>(chars);
+}
+
+
+static Vector<const char> SetVectorContents(char* chars,
+ int size,
+ bool* exists) {
+ if (!chars) {
+ *exists = false;
+ return Vector<const char>::empty();
+ }
+ chars[size] = '\0';
+ *exists = true;
+ return Vector<const char>(chars, size);
+}
+
+
+Vector<const char> ReadFile(const char* filename,
+ bool* exists,
+ bool verbose) {
+ int size;
+ char* result = ReadCharsFromFile(filename, &size, 1, verbose);
+ return SetVectorContents(result, size, exists);
+}
+
+
+Vector<const char> ReadFile(FILE* file,
+ bool* exists,
+ bool verbose) {
+ int size;
+ char* result = ReadCharsFromFile(file, &size, 1, verbose, "");
+ return SetVectorContents(result, size, exists);
+}
+
+
+int WriteCharsToFile(const char* str, int size, FILE* f) {
+ int total = 0;
+ while (total < size) {
+ int write = static_cast<int>(fwrite(str, 1, size - total, f));
+ if (write == 0) {
+ return total;
+ }
+ total += write;
+ str += write;
+ }
+ return total;
+}
+
+
+int AppendChars(const char* filename,
+ const char* str,
+ int size,
+ bool verbose) {
+ FILE* f = OS::FOpen(filename, "ab");
+ if (f == NULL) {
+ if (verbose) {
+ OS::PrintError("Cannot open file %s for writing.\n", filename);
+ }
+ return 0;
+ }
+ int written = WriteCharsToFile(str, size, f);
+ fclose(f);
+ return written;
+}
+
+
+int WriteChars(const char* filename,
+ const char* str,
+ int size,
+ bool verbose) {
+ FILE* f = OS::FOpen(filename, "wb");
+ if (f == NULL) {
+ if (verbose) {
+ OS::PrintError("Cannot open file %s for writing.\n", filename);
+ }
+ return 0;
+ }
+ int written = WriteCharsToFile(str, size, f);
+ fclose(f);
+ return written;
+}
+
+
+int WriteBytes(const char* filename,
+ const byte* bytes,
+ int size,
+ bool verbose) {
+ const char* str = reinterpret_cast<const char*>(bytes);
+ return WriteChars(filename, str, size, verbose);
+}
+
+
+
+void StringBuilder::AddFormatted(const char* format, ...) {
+ va_list arguments;
+ va_start(arguments, format);
+ AddFormattedList(format, arguments);
+ va_end(arguments);
+}
+
+
+void StringBuilder::AddFormattedList(const char* format, va_list list) {
+ ASSERT(!is_finalized() && position_ <= buffer_.length());
+ int n = OS::VSNPrintF(buffer_ + position_, format, list);
+ if (n < 0 || n >= (buffer_.length() - position_)) {
+ position_ = buffer_.length();
+ } else {
+ position_ += n;
+ }
+}
+
+
} } // namespace v8::internal
diff --git a/deps/v8/src/utils.h b/deps/v8/src/utils.h
index 753822614c..115f784758 100644
--- a/deps/v8/src/utils.h
+++ b/deps/v8/src/utils.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_UTILS_H_
#define V8_UTILS_H_
@@ -31,11 +8,12 @@
#include <limits.h>
#include <stdlib.h>
#include <string.h>
-#include <algorithm>
#include "allocation.h"
#include "checks.h"
#include "globals.h"
+#include "platform.h"
+#include "vector.h"
namespace v8 {
namespace internal {
@@ -43,10 +21,10 @@ namespace internal {
// ----------------------------------------------------------------------------
// General helper functions
-#define IS_POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0)
+#define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
-// Returns true iff x is a power of 2 (or zero). Cannot be used with the
-// maximally negative value of the type T (the -1 overflows).
+// Returns true iff x is a power of 2. Cannot be used with the maximally
+// negative value of the type T (the -1 overflows).
template <typename T>
inline bool IsPowerOf2(T x) {
return IS_POWER_OF_TWO(x);
@@ -56,7 +34,6 @@ inline bool IsPowerOf2(T x) {
// X must be a power of 2. Returns the number of trailing zeros.
inline int WhichPowerOf2(uint32_t x) {
ASSERT(IsPowerOf2(x));
- ASSERT(x != 0);
int bits = 0;
#ifdef DEBUG
int original_x = x;
@@ -250,13 +227,6 @@ T NegAbs(T a) {
}
-inline int StrLength(const char* string) {
- size_t length = strlen(string);
- ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
- return static_cast<int>(length);
-}
-
-
// TODO(svenpanne) Clean up the whole power-of-2 mess.
inline int32_t WhichPowerOf2Abs(int32_t x) {
return (x == kMinInt) ? 31 : WhichPowerOf2(Abs(x));
@@ -395,110 +365,6 @@ class Access {
};
-template <typename T>
-class Vector {
- public:
- Vector() : start_(NULL), length_(0) {}
- Vector(T* data, int length) : start_(data), length_(length) {
- ASSERT(length == 0 || (length > 0 && data != NULL));
- }
-
- static Vector<T> New(int length) {
- return Vector<T>(NewArray<T>(length), length);
- }
-
- // Returns a vector using the same backing storage as this one,
- // spanning from and including 'from', to but not including 'to'.
- Vector<T> SubVector(int from, int to) {
- SLOW_ASSERT(to <= length_);
- SLOW_ASSERT(from < to);
- ASSERT(0 <= from);
- return Vector<T>(start() + from, to - from);
- }
-
- // Returns the length of the vector.
- int length() const { return length_; }
-
- // Returns whether or not the vector is empty.
- bool is_empty() const { return length_ == 0; }
-
- // Returns the pointer to the start of the data in the vector.
- T* start() const { return start_; }
-
- // Access individual vector elements - checks bounds in debug mode.
- T& operator[](int index) const {
- ASSERT(0 <= index && index < length_);
- return start_[index];
- }
-
- const T& at(int index) const { return operator[](index); }
-
- T& first() { return start_[0]; }
-
- T& last() { return start_[length_ - 1]; }
-
- // Returns a clone of this vector with a new backing store.
- Vector<T> Clone() const {
- T* result = NewArray<T>(length_);
- for (int i = 0; i < length_; i++) result[i] = start_[i];
- return Vector<T>(result, length_);
- }
-
- void Sort(int (*cmp)(const T*, const T*)) {
- std::sort(start(), start() + length(), RawComparer(cmp));
- }
-
- void Sort() {
- std::sort(start(), start() + length());
- }
-
- void Truncate(int length) {
- ASSERT(length <= length_);
- length_ = length;
- }
-
- // Releases the array underlying this vector. Once disposed the
- // vector is empty.
- void Dispose() {
- DeleteArray(start_);
- start_ = NULL;
- length_ = 0;
- }
-
- inline Vector<T> operator+(int offset) {
- ASSERT(offset < length_);
- return Vector<T>(start_ + offset, length_ - offset);
- }
-
- // Factory method for creating empty vectors.
- static Vector<T> empty() { return Vector<T>(NULL, 0); }
-
- template<typename S>
- static Vector<T> cast(Vector<S> input) {
- return Vector<T>(reinterpret_cast<T*>(input.start()),
- input.length() * sizeof(S) / sizeof(T));
- }
-
- protected:
- void set_start(T* start) { start_ = start; }
-
- private:
- T* start_;
- int length_;
-
- class RawComparer {
- public:
- explicit RawComparer(int (*cmp)(const T*, const T*)) : cmp_(cmp) {}
- bool operator()(const T& a, const T& b) {
- return cmp_(&a, &b) < 0;
- }
-
- private:
- int (*cmp_)(const T*, const T*);
- };
-};
-
-
// A pointer that can only be set once and doesn't allow NULL values.
template<typename T>
class SetOncePointer {
@@ -536,16 +402,14 @@ class EmbeddedVector : public Vector<T> {
// When copying, make underlying Vector to reference our buffer.
EmbeddedVector(const EmbeddedVector& rhs)
: Vector<T>(rhs) {
- // TODO(jkummerow): Refactor #includes and use OS::MemCopy() instead.
- memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize);
+ OS::MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize);
set_start(buffer_);
}
EmbeddedVector& operator=(const EmbeddedVector& rhs) {
if (this == &rhs) return *this;
Vector<T>::operator=(rhs);
- // TODO(jkummerow): Refactor #includes and use OS::MemCopy() instead.
- memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize);
+ OS::MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize);
this->set_start(buffer_);
return *this;
}
@@ -555,44 +419,6 @@ class EmbeddedVector : public Vector<T> {
};
-template <typename T>
-class ScopedVector : public Vector<T> {
- public:
- explicit ScopedVector(int length) : Vector<T>(NewArray<T>(length), length) { }
- ~ScopedVector() {
- DeleteArray(this->start());
- }
-
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedVector);
-};
-
-#define STATIC_ASCII_VECTOR(x) \
- v8::internal::Vector<const uint8_t>(reinterpret_cast<const uint8_t*>(x), \
- ARRAY_SIZE(x)-1)
-
-inline Vector<const char> CStrVector(const char* data) {
- return Vector<const char>(data, StrLength(data));
-}
-
-inline Vector<const uint8_t> OneByteVector(const char* data, int length) {
- return Vector<const uint8_t>(reinterpret_cast<const uint8_t*>(data), length);
-}
-
-inline Vector<const uint8_t> OneByteVector(const char* data) {
- return OneByteVector(data, StrLength(data));
-}
-
-inline Vector<char> MutableCStrVector(char* data) {
- return Vector<char>(data, StrLength(data));
-}
-
-inline Vector<char> MutableCStrVector(char* data, int max) {
- int length = StrLength(data);
- return Vector<char>(data, (length < max) ? length : max);
-}
-
-
/*
* A class that collects values into a backing store.
* Specialized versions of the class can allow access to the backing store
@@ -920,7 +746,6 @@ struct BitCastHelper {
INLINE(static Dest cast(const Source& source)) {
Dest dest;
- // TODO(jkummerow): Refactor #includes and use OS::MemCopy() instead.
memcpy(&dest, &source, sizeof(dest));
return dest;
}
@@ -1206,6 +1031,447 @@ class ContainerPointerWrapper {
C* container_;
};
+
+// ----------------------------------------------------------------------------
+// I/O support.
+
+#if __GNUC__ >= 4
+// On gcc we can ask the compiler to check the types of %d-style format
+// specifiers and their associated arguments. TODO(erikcorry) fix this
+// so it works on MacOSX.
+#if defined(__MACH__) && defined(__APPLE__)
+#define PRINTF_CHECKING
+#define FPRINTF_CHECKING
+#define PRINTF_METHOD_CHECKING
+#define FPRINTF_METHOD_CHECKING
+#else // MacOsX.
+#define PRINTF_CHECKING __attribute__ ((format (printf, 1, 2)))
+#define FPRINTF_CHECKING __attribute__ ((format (printf, 2, 3)))
+#define PRINTF_METHOD_CHECKING __attribute__ ((format (printf, 2, 3)))
+#define FPRINTF_METHOD_CHECKING __attribute__ ((format (printf, 3, 4)))
+#endif
+#else
+#define PRINTF_CHECKING
+#define FPRINTF_CHECKING
+#define PRINTF_METHOD_CHECKING
+#define FPRINTF_METHOD_CHECKING
+#endif
+
+// Our version of printf().
+void PRINTF_CHECKING PrintF(const char* format, ...);
+void FPRINTF_CHECKING PrintF(FILE* out, const char* format, ...);
+
+// Prepends the current process ID to the output.
+void PRINTF_CHECKING PrintPID(const char* format, ...);
+
+// Our version of fflush.
+void Flush(FILE* out);
+
+inline void Flush() {
+ Flush(stdout);
+}
+
+
+// Read a line of characters after printing the prompt to stdout. The resulting
+// char* needs to be disposed off with DeleteArray by the caller.
+char* ReadLine(const char* prompt);
+
+
+// Read and return the raw bytes in a file. the size of the buffer is returned
+// in size.
+// The returned buffer must be freed by the caller.
+byte* ReadBytes(const char* filename, int* size, bool verbose = true);
+
+
+// Append size chars from str to the file given by filename.
+// The file is overwritten. Returns the number of chars written.
+int AppendChars(const char* filename,
+ const char* str,
+ int size,
+ bool verbose = true);
+
+
+// Write size chars from str to the file given by filename.
+// The file is overwritten. Returns the number of chars written.
+int WriteChars(const char* filename,
+ const char* str,
+ int size,
+ bool verbose = true);
+
+
+// Write size bytes to the file given by filename.
+// The file is overwritten. Returns the number of bytes written.
+int WriteBytes(const char* filename,
+ const byte* bytes,
+ int size,
+ bool verbose = true);
+
+
+// Write the C code
+// const char* <varname> = "<str>";
+// const int <varname>_len = <len>;
+// to the file given by filename. Only the first len chars are written.
+int WriteAsCFile(const char* filename, const char* varname,
+ const char* str, int size, bool verbose = true);
+
+
+// ----------------------------------------------------------------------------
+// Data structures
+
+template <typename T>
+inline Vector< Handle<Object> > HandleVector(v8::internal::Handle<T>* elms,
+ int length) {
+ return Vector< Handle<Object> >(
+ reinterpret_cast<v8::internal::Handle<Object>*>(elms), length);
+}
+
+
+// ----------------------------------------------------------------------------
+// Memory
+
+// Copies words from |src| to |dst|. The data spans must not overlap.
+template <typename T>
+inline void CopyWords(T* dst, const T* src, size_t num_words) {
+ STATIC_ASSERT(sizeof(T) == kPointerSize);
+ // TODO(mvstanton): disabled because mac builds are bogus failing on this
+ // assert. They are doing a signed comparison. Investigate in
+ // the morning.
+ // ASSERT(Min(dst, const_cast<T*>(src)) + num_words <=
+ // Max(dst, const_cast<T*>(src)));
+ ASSERT(num_words > 0);
+
+ // Use block copying OS::MemCopy if the segment we're copying is
+ // enough to justify the extra call/setup overhead.
+ static const size_t kBlockCopyLimit = 16;
+
+ if (num_words < kBlockCopyLimit) {
+ do {
+ num_words--;
+ *dst++ = *src++;
+ } while (num_words > 0);
+ } else {
+ OS::MemCopy(dst, src, num_words * kPointerSize);
+ }
+}
+
+
+// Copies words from |src| to |dst|. No restrictions.
+template <typename T>
+inline void MoveWords(T* dst, const T* src, size_t num_words) {
+ STATIC_ASSERT(sizeof(T) == kPointerSize);
+ ASSERT(num_words > 0);
+
+ // Use block copying OS::MemCopy if the segment we're copying is
+ // enough to justify the extra call/setup overhead.
+ static const size_t kBlockCopyLimit = 16;
+
+ if (num_words < kBlockCopyLimit &&
+ ((dst < src) || (dst >= (src + num_words * kPointerSize)))) {
+ T* end = dst + num_words;
+ do {
+ num_words--;
+ *dst++ = *src++;
+ } while (num_words > 0);
+ } else {
+ OS::MemMove(dst, src, num_words * kPointerSize);
+ }
+}
+
+
+// Copies data from |src| to |dst|. The data spans must not overlap.
+template <typename T>
+inline void CopyBytes(T* dst, const T* src, size_t num_bytes) {
+ STATIC_ASSERT(sizeof(T) == 1);
+ ASSERT(Min(dst, const_cast<T*>(src)) + num_bytes <=
+ Max(dst, const_cast<T*>(src)));
+ if (num_bytes == 0) return;
+
+ // Use block copying OS::MemCopy if the segment we're copying is
+ // enough to justify the extra call/setup overhead.
+ static const int kBlockCopyLimit = OS::kMinComplexMemCopy;
+
+ if (num_bytes < static_cast<size_t>(kBlockCopyLimit)) {
+ do {
+ num_bytes--;
+ *dst++ = *src++;
+ } while (num_bytes > 0);
+ } else {
+ OS::MemCopy(dst, src, num_bytes);
+ }
+}
+
+
+template <typename T, typename U>
+inline void MemsetPointer(T** dest, U* value, int counter) {
+#ifdef DEBUG
+ T* a = NULL;
+ U* b = NULL;
+ a = b; // Fake assignment to check assignability.
+ USE(a);
+#endif // DEBUG
+#if V8_HOST_ARCH_IA32
+#define STOS "stosl"
+#elif V8_HOST_ARCH_X64
+#define STOS "stosq"
+#endif
+#if defined(__native_client__)
+ // This STOS sequence does not validate for x86_64 Native Client.
+ // Here we #undef STOS to force use of the slower C version.
+ // TODO(bradchen): Profile V8 and implement a faster REP STOS
+ // here if the profile indicates it matters.
+#undef STOS
+#endif
+
+#if defined(MEMORY_SANITIZER)
+ // MemorySanitizer does not understand inline assembly.
+#undef STOS
+#endif
+
+#if defined(__GNUC__) && defined(STOS)
+ asm volatile(
+ "cld;"
+ "rep ; " STOS
+ : "+&c" (counter), "+&D" (dest)
+ : "a" (value)
+ : "memory", "cc");
+#else
+ for (int i = 0; i < counter; i++) {
+ dest[i] = value;
+ }
+#endif
+
+#undef STOS
+}
+
+
+// Simple wrapper that allows an ExternalString to refer to a
+// Vector<const char>. Doesn't assume ownership of the data.
+class AsciiStringAdapter: public v8::String::ExternalAsciiStringResource {
+ public:
+ explicit AsciiStringAdapter(Vector<const char> data) : data_(data) {}
+
+ virtual const char* data() const { return data_.start(); }
+
+ virtual size_t length() const { return data_.length(); }
+
+ private:
+ Vector<const char> data_;
+};
+
+
+// Simple support to read a file into a 0-terminated C-string.
+// The returned buffer must be freed by the caller.
+// On return, *exits tells whether the file existed.
+Vector<const char> ReadFile(const char* filename,
+ bool* exists,
+ bool verbose = true);
+Vector<const char> ReadFile(FILE* file,
+ bool* exists,
+ bool verbose = true);
+
+
+template <typename sourcechar, typename sinkchar>
+INLINE(static void CopyCharsUnsigned(sinkchar* dest,
+ const sourcechar* src,
+ int chars));
+#if defined(V8_HOST_ARCH_ARM)
+INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars));
+INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars));
+INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars));
+#elif defined(V8_HOST_ARCH_MIPS)
+INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars));
+INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars));
+#endif
+
+// Copy from ASCII/16bit chars to ASCII/16bit chars.
+template <typename sourcechar, typename sinkchar>
+INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, int chars));
+
+template<typename sourcechar, typename sinkchar>
+void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
+ ASSERT(sizeof(sourcechar) <= 2);
+ ASSERT(sizeof(sinkchar) <= 2);
+ if (sizeof(sinkchar) == 1) {
+ if (sizeof(sourcechar) == 1) {
+ CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
+ reinterpret_cast<const uint8_t*>(src),
+ chars);
+ } else {
+ CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
+ reinterpret_cast<const uint16_t*>(src),
+ chars);
+ }
+ } else {
+ if (sizeof(sourcechar) == 1) {
+ CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
+ reinterpret_cast<const uint8_t*>(src),
+ chars);
+ } else {
+ CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
+ reinterpret_cast<const uint16_t*>(src),
+ chars);
+ }
+ }
+}
+
+template <typename sourcechar, typename sinkchar>
+void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, int chars) {
+ sinkchar* limit = dest + chars;
+#ifdef V8_HOST_CAN_READ_UNALIGNED
+ if (sizeof(*dest) == sizeof(*src)) {
+ if (chars >= static_cast<int>(OS::kMinComplexMemCopy / sizeof(*dest))) {
+ OS::MemCopy(dest, src, chars * sizeof(*dest));
+ return;
+ }
+ // Number of characters in a uintptr_t.
+ static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest); // NOLINT
+ ASSERT(dest + kStepSize > dest); // Check for overflow.
+ while (dest + kStepSize <= limit) {
+ *reinterpret_cast<uintptr_t*>(dest) =
+ *reinterpret_cast<const uintptr_t*>(src);
+ dest += kStepSize;
+ src += kStepSize;
+ }
+ }
+#endif
+ while (dest < limit) {
+ *dest++ = static_cast<sinkchar>(*src++);
+ }
+}
+
+
+#if defined(V8_HOST_ARCH_ARM)
+void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
+ switch (static_cast<unsigned>(chars)) {
+ case 0:
+ break;
+ case 1:
+ *dest = *src;
+ break;
+ case 2:
+ memcpy(dest, src, 2);
+ break;
+ case 3:
+ memcpy(dest, src, 3);
+ break;
+ case 4:
+ memcpy(dest, src, 4);
+ break;
+ case 5:
+ memcpy(dest, src, 5);
+ break;
+ case 6:
+ memcpy(dest, src, 6);
+ break;
+ case 7:
+ memcpy(dest, src, 7);
+ break;
+ case 8:
+ memcpy(dest, src, 8);
+ break;
+ case 9:
+ memcpy(dest, src, 9);
+ break;
+ case 10:
+ memcpy(dest, src, 10);
+ break;
+ case 11:
+ memcpy(dest, src, 11);
+ break;
+ case 12:
+ memcpy(dest, src, 12);
+ break;
+ case 13:
+ memcpy(dest, src, 13);
+ break;
+ case 14:
+ memcpy(dest, src, 14);
+ break;
+ case 15:
+ memcpy(dest, src, 15);
+ break;
+ default:
+ OS::MemCopy(dest, src, chars);
+ break;
+ }
+}
+
+
+void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars) {
+ if (chars >= OS::kMinComplexConvertMemCopy) {
+ OS::MemCopyUint16Uint8(dest, src, chars);
+ } else {
+ OS::MemCopyUint16Uint8Wrapper(dest, src, chars);
+ }
+}
+
+
+void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
+ switch (static_cast<unsigned>(chars)) {
+ case 0:
+ break;
+ case 1:
+ *dest = *src;
+ break;
+ case 2:
+ memcpy(dest, src, 4);
+ break;
+ case 3:
+ memcpy(dest, src, 6);
+ break;
+ case 4:
+ memcpy(dest, src, 8);
+ break;
+ case 5:
+ memcpy(dest, src, 10);
+ break;
+ case 6:
+ memcpy(dest, src, 12);
+ break;
+ case 7:
+ memcpy(dest, src, 14);
+ break;
+ default:
+ OS::MemCopy(dest, src, chars * sizeof(*dest));
+ break;
+ }
+}
+
+
+#elif defined(V8_HOST_ARCH_MIPS)
+void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
+ if (chars < OS::kMinComplexMemCopy) {
+ memcpy(dest, src, chars);
+ } else {
+ OS::MemCopy(dest, src, chars);
+ }
+}
+
+void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
+ if (chars < OS::kMinComplexMemCopy) {
+ memcpy(dest, src, chars * sizeof(*dest));
+ } else {
+ OS::MemCopy(dest, src, chars * sizeof(*dest));
+ }
+}
+#endif
+
+
+class StringBuilder : public SimpleStringBuilder {
+ public:
+ explicit StringBuilder(int size) : SimpleStringBuilder(size) { }
+ StringBuilder(char* buffer, int size) : SimpleStringBuilder(buffer, size) { }
+
+ // Add formatted contents to the builder just like printf().
+ void AddFormatted(const char* format, ...);
+
+ // Add formatted contents like printf based on a va_list.
+ void AddFormattedList(const char* format, va_list list);
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
+};
+
+
} } // namespace v8::internal
#endif // V8_UTILS_H_
diff --git a/deps/v8/src/utils/random-number-generator.cc b/deps/v8/src/utils/random-number-generator.cc
index d40102f91f..92114b0e25 100644
--- a/deps/v8/src/utils/random-number-generator.cc
+++ b/deps/v8/src/utils/random-number-generator.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "utils/random-number-generator.h"
diff --git a/deps/v8/src/utils/random-number-generator.h b/deps/v8/src/utils/random-number-generator.h
index cc7d7395e6..331cffae77 100644
--- a/deps/v8/src/utils/random-number-generator.h
+++ b/deps/v8/src/utils/random-number-generator.h
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_UTILS_RANDOM_NUMBER_GENERATOR_H_
#define V8_UTILS_RANDOM_NUMBER_GENERATOR_H_
diff --git a/deps/v8/src/v8-counters.cc b/deps/v8/src/v8-counters.cc
deleted file mode 100644
index c899b289a5..0000000000
--- a/deps/v8/src/v8-counters.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "v8.h"
-
-#include "v8-counters.h"
-
-namespace v8 {
-namespace internal {
-
-Counters::Counters(Isolate* isolate) {
-#define HT(name, caption) \
- name##_ = HistogramTimer(#caption, 0, 10000, 50, isolate);
- HISTOGRAM_TIMER_LIST(HT)
-#undef HT
-
-#define HP(name, caption) \
- name##_ = Histogram(#caption, 0, 101, 100, isolate);
- HISTOGRAM_PERCENTAGE_LIST(HP)
-#undef HP
-
-#define HM(name, caption) \
- name##_ = Histogram(#caption, 1000, 500000, 50, isolate);
- HISTOGRAM_MEMORY_LIST(HM)
-#undef HM
-
-#define SC(name, caption) \
- name##_ = StatsCounter(isolate, "c:" #caption);
-
- STATS_COUNTER_LIST_1(SC)
- STATS_COUNTER_LIST_2(SC)
-#undef SC
-
-#define SC(name) \
- count_of_##name##_ = StatsCounter(isolate, "c:" "V8.CountOf_" #name); \
- size_of_##name##_ = StatsCounter(isolate, "c:" "V8.SizeOf_" #name);
- INSTANCE_TYPE_LIST(SC)
-#undef SC
-
-#define SC(name) \
- count_of_CODE_TYPE_##name##_ = \
- StatsCounter(isolate, "c:" "V8.CountOf_CODE_TYPE-" #name); \
- size_of_CODE_TYPE_##name##_ = \
- StatsCounter(isolate, "c:" "V8.SizeOf_CODE_TYPE-" #name);
- CODE_KIND_LIST(SC)
-#undef SC
-
-#define SC(name) \
- count_of_FIXED_ARRAY_##name##_ = \
- StatsCounter(isolate, "c:" "V8.CountOf_FIXED_ARRAY-" #name); \
- size_of_FIXED_ARRAY_##name##_ = \
- StatsCounter(isolate, "c:" "V8.SizeOf_FIXED_ARRAY-" #name);
- FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC)
-#undef SC
-
-#define SC(name) \
- count_of_CODE_AGE_##name##_ = \
- StatsCounter(isolate, "c:" "V8.CountOf_CODE_AGE-" #name); \
- size_of_CODE_AGE_##name##_ = \
- StatsCounter(isolate, "c:" "V8.SizeOf_CODE_AGE-" #name);
- CODE_AGE_LIST_COMPLETE(SC)
-#undef SC
-}
-
-
-void Counters::ResetHistograms() {
-#define HT(name, caption) name##_.Reset();
- HISTOGRAM_TIMER_LIST(HT)
-#undef HT
-
-#define HP(name, caption) name##_.Reset();
- HISTOGRAM_PERCENTAGE_LIST(HP)
-#undef HP
-
-#define HM(name, caption) name##_.Reset();
- HISTOGRAM_MEMORY_LIST(HM)
-#undef HM
-}
-
-} } // namespace v8::internal
diff --git a/deps/v8/src/v8-counters.h b/deps/v8/src/v8-counters.h
deleted file mode 100644
index 0bd4955105..0000000000
--- a/deps/v8/src/v8-counters.h
+++ /dev/null
@@ -1,435 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef V8_V8_COUNTERS_H_
-#define V8_V8_COUNTERS_H_
-
-#include "allocation.h"
-#include "counters.h"
-#include "objects.h"
-#include "v8globals.h"
-
-namespace v8 {
-namespace internal {
-
-#define HISTOGRAM_TIMER_LIST(HT) \
- /* Garbage collection timers. */ \
- HT(gc_compactor, V8.GCCompactor) \
- HT(gc_scavenger, V8.GCScavenger) \
- HT(gc_context, V8.GCContext) /* GC context cleanup time */ \
- /* Parsing timers. */ \
- HT(parse, V8.Parse) \
- HT(parse_lazy, V8.ParseLazy) \
- HT(pre_parse, V8.PreParse) \
- /* Total compilation times. */ \
- HT(compile, V8.Compile) \
- HT(compile_eval, V8.CompileEval) \
- HT(compile_lazy, V8.CompileLazy)
-
-#define HISTOGRAM_PERCENTAGE_LIST(HP) \
- /* Heap fragmentation. */ \
- HP(external_fragmentation_total, \
- V8.MemoryExternalFragmentationTotal) \
- HP(external_fragmentation_old_pointer_space, \
- V8.MemoryExternalFragmentationOldPointerSpace) \
- HP(external_fragmentation_old_data_space, \
- V8.MemoryExternalFragmentationOldDataSpace) \
- HP(external_fragmentation_code_space, \
- V8.MemoryExternalFragmentationCodeSpace) \
- HP(external_fragmentation_map_space, \
- V8.MemoryExternalFragmentationMapSpace) \
- HP(external_fragmentation_cell_space, \
- V8.MemoryExternalFragmentationCellSpace) \
- HP(external_fragmentation_property_cell_space, \
- V8.MemoryExternalFragmentationPropertyCellSpace) \
- HP(external_fragmentation_lo_space, \
- V8.MemoryExternalFragmentationLoSpace) \
- /* Percentages of heap committed to each space. */ \
- HP(heap_fraction_new_space, \
- V8.MemoryHeapFractionNewSpace) \
- HP(heap_fraction_old_pointer_space, \
- V8.MemoryHeapFractionOldPointerSpace) \
- HP(heap_fraction_old_data_space, \
- V8.MemoryHeapFractionOldDataSpace) \
- HP(heap_fraction_code_space, \
- V8.MemoryHeapFractionCodeSpace) \
- HP(heap_fraction_map_space, \
- V8.MemoryHeapFractionMapSpace) \
- HP(heap_fraction_cell_space, \
- V8.MemoryHeapFractionCellSpace) \
- HP(heap_fraction_property_cell_space, \
- V8.MemoryHeapFractionPropertyCellSpace) \
- HP(heap_fraction_lo_space, \
- V8.MemoryHeapFractionLoSpace) \
- /* Percentage of crankshafted codegen. */ \
- HP(codegen_fraction_crankshaft, \
- V8.CodegenFractionCrankshaft) \
-
-
-#define HISTOGRAM_MEMORY_LIST(HM) \
- HM(heap_sample_total_committed, V8.MemoryHeapSampleTotalCommitted) \
- HM(heap_sample_total_used, V8.MemoryHeapSampleTotalUsed) \
- HM(heap_sample_map_space_committed, \
- V8.MemoryHeapSampleMapSpaceCommitted) \
- HM(heap_sample_cell_space_committed, \
- V8.MemoryHeapSampleCellSpaceCommitted) \
- HM(heap_sample_property_cell_space_committed, \
- V8.MemoryHeapSamplePropertyCellSpaceCommitted) \
- HM(heap_sample_code_space_committed, \
- V8.MemoryHeapSampleCodeSpaceCommitted) \
- HM(heap_sample_maximum_committed, \
- V8.MemoryHeapSampleMaximumCommitted) \
-
-
-// WARNING: STATS_COUNTER_LIST_* is a very large macro that is causing MSVC
-// Intellisense to crash. It was broken into two macros (each of length 40
-// lines) rather than one macro (of length about 80 lines) to work around
-// this problem. Please avoid using recursive macros of this length when
-// possible.
-#define STATS_COUNTER_LIST_1(SC) \
- /* Global Handle Count*/ \
- SC(global_handles, V8.GlobalHandles) \
- /* OS Memory allocated */ \
- SC(memory_allocated, V8.OsMemoryAllocated) \
- SC(normalized_maps, V8.NormalizedMaps) \
- SC(props_to_dictionary, V8.ObjectPropertiesToDictionary) \
- SC(elements_to_dictionary, V8.ObjectElementsToDictionary) \
- SC(alive_after_last_gc, V8.AliveAfterLastGC) \
- SC(objs_since_last_young, V8.ObjsSinceLastYoung) \
- SC(objs_since_last_full, V8.ObjsSinceLastFull) \
- SC(string_table_capacity, V8.StringTableCapacity) \
- SC(number_of_symbols, V8.NumberOfSymbols) \
- SC(script_wrappers, V8.ScriptWrappers) \
- SC(call_initialize_stubs, V8.CallInitializeStubs) \
- SC(call_premonomorphic_stubs, V8.CallPreMonomorphicStubs) \
- SC(call_normal_stubs, V8.CallNormalStubs) \
- SC(call_megamorphic_stubs, V8.CallMegamorphicStubs) \
- SC(arguments_adaptors, V8.ArgumentsAdaptors) \
- SC(compilation_cache_hits, V8.CompilationCacheHits) \
- SC(compilation_cache_misses, V8.CompilationCacheMisses) \
- SC(string_ctor_calls, V8.StringConstructorCalls) \
- SC(string_ctor_conversions, V8.StringConstructorConversions) \
- SC(string_ctor_cached_number, V8.StringConstructorCachedNumber) \
- SC(string_ctor_string_value, V8.StringConstructorStringValue) \
- SC(string_ctor_gc_required, V8.StringConstructorGCRequired) \
- /* Amount of evaled source code. */ \
- SC(total_eval_size, V8.TotalEvalSize) \
- /* Amount of loaded source code. */ \
- SC(total_load_size, V8.TotalLoadSize) \
- /* Amount of parsed source code. */ \
- SC(total_parse_size, V8.TotalParseSize) \
- /* Amount of source code skipped over using preparsing. */ \
- SC(total_preparse_skipped, V8.TotalPreparseSkipped) \
- /* Number of symbol lookups skipped using preparsing */ \
- SC(total_preparse_symbols_skipped, V8.TotalPreparseSymbolSkipped) \
- /* Amount of compiled source code. */ \
- SC(total_compile_size, V8.TotalCompileSize) \
- /* Amount of source code compiled with the full codegen. */ \
- SC(total_full_codegen_source_size, V8.TotalFullCodegenSourceSize) \
- /* Number of contexts created from scratch. */ \
- SC(contexts_created_from_scratch, V8.ContextsCreatedFromScratch) \
- /* Number of contexts created by partial snapshot. */ \
- SC(contexts_created_by_snapshot, V8.ContextsCreatedBySnapshot) \
- /* Number of code objects found from pc. */ \
- SC(pc_to_code, V8.PcToCode) \
- SC(pc_to_code_cached, V8.PcToCodeCached) \
- /* The store-buffer implementation of the write barrier. */ \
- SC(store_buffer_compactions, V8.StoreBufferCompactions) \
- SC(store_buffer_overflows, V8.StoreBufferOverflows)
-
-
-#define STATS_COUNTER_LIST_2(SC) \
- /* Number of code stubs. */ \
- SC(code_stubs, V8.CodeStubs) \
- /* Amount of stub code. */ \
- SC(total_stubs_code_size, V8.TotalStubsCodeSize) \
- /* Amount of (JS) compiled code. */ \
- SC(total_compiled_code_size, V8.TotalCompiledCodeSize) \
- SC(gc_compactor_caused_by_request, V8.GCCompactorCausedByRequest) \
- SC(gc_compactor_caused_by_promoted_data, \
- V8.GCCompactorCausedByPromotedData) \
- SC(gc_compactor_caused_by_oldspace_exhaustion, \
- V8.GCCompactorCausedByOldspaceExhaustion) \
- SC(gc_last_resort_from_js, V8.GCLastResortFromJS) \
- SC(gc_last_resort_from_handles, V8.GCLastResortFromHandles) \
- /* How is the generic keyed-load stub used? */ \
- SC(keyed_load_generic_smi, V8.KeyedLoadGenericSmi) \
- SC(keyed_load_generic_symbol, V8.KeyedLoadGenericSymbol) \
- SC(keyed_load_generic_lookup_cache, V8.KeyedLoadGenericLookupCache) \
- SC(keyed_load_generic_slow, V8.KeyedLoadGenericSlow) \
- SC(keyed_load_polymorphic_stubs, V8.KeyedLoadPolymorphicStubs) \
- SC(keyed_load_external_array_slow, V8.KeyedLoadExternalArraySlow) \
- /* How is the generic keyed-call stub used? */ \
- SC(keyed_call_generic_smi_fast, V8.KeyedCallGenericSmiFast) \
- SC(keyed_call_generic_smi_dict, V8.KeyedCallGenericSmiDict) \
- SC(keyed_call_generic_lookup_cache, V8.KeyedCallGenericLookupCache) \
- SC(keyed_call_generic_lookup_dict, V8.KeyedCallGenericLookupDict) \
- SC(keyed_call_generic_slow, V8.KeyedCallGenericSlow) \
- SC(keyed_call_generic_slow_load, V8.KeyedCallGenericSlowLoad) \
- SC(named_load_global_stub, V8.NamedLoadGlobalStub) \
- SC(named_store_global_inline, V8.NamedStoreGlobalInline) \
- SC(named_store_global_inline_miss, V8.NamedStoreGlobalInlineMiss) \
- SC(keyed_store_polymorphic_stubs, V8.KeyedStorePolymorphicStubs) \
- SC(keyed_store_external_array_slow, V8.KeyedStoreExternalArraySlow) \
- SC(store_normal_miss, V8.StoreNormalMiss) \
- SC(store_normal_hit, V8.StoreNormalHit) \
- SC(cow_arrays_created_stub, V8.COWArraysCreatedStub) \
- SC(cow_arrays_created_runtime, V8.COWArraysCreatedRuntime) \
- SC(cow_arrays_converted, V8.COWArraysConverted) \
- SC(call_miss, V8.CallMiss) \
- SC(keyed_call_miss, V8.KeyedCallMiss) \
- SC(load_miss, V8.LoadMiss) \
- SC(keyed_load_miss, V8.KeyedLoadMiss) \
- SC(call_const, V8.CallConst) \
- SC(call_const_fast_api, V8.CallConstFastApi) \
- SC(call_const_interceptor, V8.CallConstInterceptor) \
- SC(call_const_interceptor_fast_api, V8.CallConstInterceptorFastApi) \
- SC(call_global_inline, V8.CallGlobalInline) \
- SC(call_global_inline_miss, V8.CallGlobalInlineMiss) \
- SC(constructed_objects, V8.ConstructedObjects) \
- SC(constructed_objects_runtime, V8.ConstructedObjectsRuntime) \
- SC(negative_lookups, V8.NegativeLookups) \
- SC(negative_lookups_miss, V8.NegativeLookupsMiss) \
- SC(megamorphic_stub_cache_probes, V8.MegamorphicStubCacheProbes) \
- SC(megamorphic_stub_cache_misses, V8.MegamorphicStubCacheMisses) \
- SC(megamorphic_stub_cache_updates, V8.MegamorphicStubCacheUpdates) \
- SC(array_function_runtime, V8.ArrayFunctionRuntime) \
- SC(array_function_native, V8.ArrayFunctionNative) \
- SC(for_in, V8.ForIn) \
- SC(enum_cache_hits, V8.EnumCacheHits) \
- SC(enum_cache_misses, V8.EnumCacheMisses) \
- SC(zone_segment_bytes, V8.ZoneSegmentBytes) \
- SC(fast_new_closure_total, V8.FastNewClosureTotal) \
- SC(fast_new_closure_try_optimized, V8.FastNewClosureTryOptimized) \
- SC(fast_new_closure_install_optimized, V8.FastNewClosureInstallOptimized) \
- SC(string_add_runtime, V8.StringAddRuntime) \
- SC(string_add_native, V8.StringAddNative) \
- SC(string_add_runtime_ext_to_ascii, V8.StringAddRuntimeExtToAscii) \
- SC(sub_string_runtime, V8.SubStringRuntime) \
- SC(sub_string_native, V8.SubStringNative) \
- SC(string_add_make_two_char, V8.StringAddMakeTwoChar) \
- SC(string_compare_native, V8.StringCompareNative) \
- SC(string_compare_runtime, V8.StringCompareRuntime) \
- SC(regexp_entry_runtime, V8.RegExpEntryRuntime) \
- SC(regexp_entry_native, V8.RegExpEntryNative) \
- SC(number_to_string_native, V8.NumberToStringNative) \
- SC(number_to_string_runtime, V8.NumberToStringRuntime) \
- SC(math_acos, V8.MathAcos) \
- SC(math_asin, V8.MathAsin) \
- SC(math_atan, V8.MathAtan) \
- SC(math_atan2, V8.MathAtan2) \
- SC(math_exp, V8.MathExp) \
- SC(math_floor, V8.MathFloor) \
- SC(math_log, V8.MathLog) \
- SC(math_pow, V8.MathPow) \
- SC(math_round, V8.MathRound) \
- SC(math_sqrt, V8.MathSqrt) \
- SC(stack_interrupts, V8.StackInterrupts) \
- SC(runtime_profiler_ticks, V8.RuntimeProfilerTicks) \
- SC(bounds_checks_eliminated, V8.BoundsChecksEliminated) \
- SC(bounds_checks_hoisted, V8.BoundsChecksHoisted) \
- SC(soft_deopts_requested, V8.SoftDeoptsRequested) \
- SC(soft_deopts_inserted, V8.SoftDeoptsInserted) \
- SC(soft_deopts_executed, V8.SoftDeoptsExecuted) \
- /* Number of write barriers in generated code. */ \
- SC(write_barriers_dynamic, V8.WriteBarriersDynamic) \
- SC(write_barriers_static, V8.WriteBarriersStatic) \
- SC(new_space_bytes_available, V8.MemoryNewSpaceBytesAvailable) \
- SC(new_space_bytes_committed, V8.MemoryNewSpaceBytesCommitted) \
- SC(new_space_bytes_used, V8.MemoryNewSpaceBytesUsed) \
- SC(old_pointer_space_bytes_available, \
- V8.MemoryOldPointerSpaceBytesAvailable) \
- SC(old_pointer_space_bytes_committed, \
- V8.MemoryOldPointerSpaceBytesCommitted) \
- SC(old_pointer_space_bytes_used, V8.MemoryOldPointerSpaceBytesUsed) \
- SC(old_data_space_bytes_available, V8.MemoryOldDataSpaceBytesAvailable) \
- SC(old_data_space_bytes_committed, V8.MemoryOldDataSpaceBytesCommitted) \
- SC(old_data_space_bytes_used, V8.MemoryOldDataSpaceBytesUsed) \
- SC(code_space_bytes_available, V8.MemoryCodeSpaceBytesAvailable) \
- SC(code_space_bytes_committed, V8.MemoryCodeSpaceBytesCommitted) \
- SC(code_space_bytes_used, V8.MemoryCodeSpaceBytesUsed) \
- SC(map_space_bytes_available, V8.MemoryMapSpaceBytesAvailable) \
- SC(map_space_bytes_committed, V8.MemoryMapSpaceBytesCommitted) \
- SC(map_space_bytes_used, V8.MemoryMapSpaceBytesUsed) \
- SC(cell_space_bytes_available, V8.MemoryCellSpaceBytesAvailable) \
- SC(cell_space_bytes_committed, V8.MemoryCellSpaceBytesCommitted) \
- SC(cell_space_bytes_used, V8.MemoryCellSpaceBytesUsed) \
- SC(property_cell_space_bytes_available, \
- V8.MemoryPropertyCellSpaceBytesAvailable) \
- SC(property_cell_space_bytes_committed, \
- V8.MemoryPropertyCellSpaceBytesCommitted) \
- SC(property_cell_space_bytes_used, \
- V8.MemoryPropertyCellSpaceBytesUsed) \
- SC(lo_space_bytes_available, V8.MemoryLoSpaceBytesAvailable) \
- SC(lo_space_bytes_committed, V8.MemoryLoSpaceBytesCommitted) \
- SC(lo_space_bytes_used, V8.MemoryLoSpaceBytesUsed)
-
-
-// This file contains all the v8 counters that are in use.
-class Counters {
- public:
-#define HT(name, caption) \
- HistogramTimer* name() { return &name##_; }
- HISTOGRAM_TIMER_LIST(HT)
-#undef HT
-
-#define HP(name, caption) \
- Histogram* name() { return &name##_; }
- HISTOGRAM_PERCENTAGE_LIST(HP)
-#undef HP
-
-#define HM(name, caption) \
- Histogram* name() { return &name##_; }
- HISTOGRAM_MEMORY_LIST(HM)
-#undef HM
-
-#define SC(name, caption) \
- StatsCounter* name() { return &name##_; }
- STATS_COUNTER_LIST_1(SC)
- STATS_COUNTER_LIST_2(SC)
-#undef SC
-
-#define SC(name) \
- StatsCounter* count_of_##name() { return &count_of_##name##_; } \
- StatsCounter* size_of_##name() { return &size_of_##name##_; }
- INSTANCE_TYPE_LIST(SC)
-#undef SC
-
-#define SC(name) \
- StatsCounter* count_of_CODE_TYPE_##name() \
- { return &count_of_CODE_TYPE_##name##_; } \
- StatsCounter* size_of_CODE_TYPE_##name() \
- { return &size_of_CODE_TYPE_##name##_; }
- CODE_KIND_LIST(SC)
-#undef SC
-
-#define SC(name) \
- StatsCounter* count_of_FIXED_ARRAY_##name() \
- { return &count_of_FIXED_ARRAY_##name##_; } \
- StatsCounter* size_of_FIXED_ARRAY_##name() \
- { return &size_of_FIXED_ARRAY_##name##_; }
- FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC)
-#undef SC
-
-#define SC(name) \
- StatsCounter* count_of_CODE_AGE_##name() \
- { return &count_of_CODE_AGE_##name##_; } \
- StatsCounter* size_of_CODE_AGE_##name() \
- { return &size_of_CODE_AGE_##name##_; }
- CODE_AGE_LIST_COMPLETE(SC)
-#undef SC
-
- enum Id {
-#define RATE_ID(name, caption) k_##name,
- HISTOGRAM_TIMER_LIST(RATE_ID)
-#undef RATE_ID
-#define PERCENTAGE_ID(name, caption) k_##name,
- HISTOGRAM_PERCENTAGE_LIST(PERCENTAGE_ID)
-#undef PERCENTAGE_ID
-#define MEMORY_ID(name, caption) k_##name,
- HISTOGRAM_MEMORY_LIST(MEMORY_ID)
-#undef MEMORY_ID
-#define COUNTER_ID(name, caption) k_##name,
- STATS_COUNTER_LIST_1(COUNTER_ID)
- STATS_COUNTER_LIST_2(COUNTER_ID)
-#undef COUNTER_ID
-#define COUNTER_ID(name) kCountOf##name, kSizeOf##name,
- INSTANCE_TYPE_LIST(COUNTER_ID)
-#undef COUNTER_ID
-#define COUNTER_ID(name) kCountOfCODE_TYPE_##name, \
- kSizeOfCODE_TYPE_##name,
- CODE_KIND_LIST(COUNTER_ID)
-#undef COUNTER_ID
-#define COUNTER_ID(name) kCountOfFIXED_ARRAY__##name, \
- kSizeOfFIXED_ARRAY__##name,
- FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(COUNTER_ID)
-#undef COUNTER_ID
-#define COUNTER_ID(name) kCountOfCODE_AGE__##name, \
- kSizeOfCODE_AGE__##name,
- CODE_AGE_LIST_COMPLETE(COUNTER_ID)
-#undef COUNTER_ID
- stats_counter_count
- };
-
- void ResetHistograms();
-
- private:
-#define HT(name, caption) \
- HistogramTimer name##_;
- HISTOGRAM_TIMER_LIST(HT)
-#undef HT
-
-#define HP(name, caption) \
- Histogram name##_;
- HISTOGRAM_PERCENTAGE_LIST(HP)
-#undef HP
-
-#define HM(name, caption) \
- Histogram name##_;
- HISTOGRAM_MEMORY_LIST(HM)
-#undef HM
-
-#define SC(name, caption) \
- StatsCounter name##_;
- STATS_COUNTER_LIST_1(SC)
- STATS_COUNTER_LIST_2(SC)
-#undef SC
-
-#define SC(name) \
- StatsCounter size_of_##name##_; \
- StatsCounter count_of_##name##_;
- INSTANCE_TYPE_LIST(SC)
-#undef SC
-
-#define SC(name) \
- StatsCounter size_of_CODE_TYPE_##name##_; \
- StatsCounter count_of_CODE_TYPE_##name##_;
- CODE_KIND_LIST(SC)
-#undef SC
-
-#define SC(name) \
- StatsCounter size_of_FIXED_ARRAY_##name##_; \
- StatsCounter count_of_FIXED_ARRAY_##name##_;
- FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC)
-#undef SC
-
-#define SC(name) \
- StatsCounter size_of_CODE_AGE_##name##_; \
- StatsCounter count_of_CODE_AGE_##name##_;
- CODE_AGE_LIST_COMPLETE(SC)
-#undef SC
-
- friend class Isolate;
-
- explicit Counters(Isolate* isolate);
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(Counters);
-};
-
-} } // namespace v8::internal
-
-#endif // V8_V8_COUNTERS_H_
diff --git a/deps/v8/src/v8.cc b/deps/v8/src/v8.cc
index b49e0eb5f2..f8156ecbd7 100644
--- a/deps/v8/src/v8.cc
+++ b/deps/v8/src/v8.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -53,29 +30,14 @@ namespace internal {
V8_DECLARE_ONCE(init_once);
-List<CallCompletedCallback>* V8::call_completed_callbacks_ = NULL;
v8::ArrayBuffer::Allocator* V8::array_buffer_allocator_ = NULL;
v8::Platform* V8::platform_ = NULL;
bool V8::Initialize(Deserializer* des) {
InitializeOncePerProcess();
-
- // The current thread may not yet had entered an isolate to run.
- // Note the Isolate::Current() may be non-null because for various
- // initialization purposes an initializing thread may be assigned an isolate
- // but not actually enter it.
- if (i::Isolate::CurrentPerIsolateThreadData() == NULL) {
- i::Isolate::EnterDefaultIsolate();
- }
-
- ASSERT(i::Isolate::CurrentPerIsolateThreadData() != NULL);
- ASSERT(i::Isolate::CurrentPerIsolateThreadData()->thread_id().Equals(
- i::ThreadId::Current()));
- ASSERT(i::Isolate::CurrentPerIsolateThreadData()->isolate() ==
- i::Isolate::Current());
-
- Isolate* isolate = Isolate::Current();
+ Isolate* isolate = Isolate::UncheckedCurrent();
+ if (isolate == NULL) return true;
if (isolate->IsDead()) return false;
if (isolate->IsInitialized()) return true;
@@ -108,10 +70,8 @@ void V8::TearDown() {
RegisteredExtension::UnregisterAll();
Isolate::GlobalTearDown();
- delete call_completed_callbacks_;
- call_completed_callbacks_ = NULL;
-
Sampler::TearDown();
+ Serializer::TearDown();
#ifdef V8_USE_DEFAULT_PLATFORM
DefaultPlatform* platform = static_cast<DefaultPlatform*>(platform_);
@@ -127,65 +87,9 @@ void V8::SetReturnAddressLocationResolver(
}
-void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
- if (call_completed_callbacks_ == NULL) { // Lazy init.
- call_completed_callbacks_ = new List<CallCompletedCallback>();
- }
- for (int i = 0; i < call_completed_callbacks_->length(); i++) {
- if (callback == call_completed_callbacks_->at(i)) return;
- }
- call_completed_callbacks_->Add(callback);
-}
-
-
-void V8::RemoveCallCompletedCallback(CallCompletedCallback callback) {
- if (call_completed_callbacks_ == NULL) return;
- for (int i = 0; i < call_completed_callbacks_->length(); i++) {
- if (callback == call_completed_callbacks_->at(i)) {
- call_completed_callbacks_->Remove(i);
- }
- }
-}
-
-
-void V8::FireCallCompletedCallback(Isolate* isolate) {
- bool has_call_completed_callbacks = call_completed_callbacks_ != NULL;
- bool run_microtasks = isolate->autorun_microtasks() &&
- isolate->microtask_pending();
- if (!has_call_completed_callbacks && !run_microtasks) return;
-
- HandleScopeImplementer* handle_scope_implementer =
- isolate->handle_scope_implementer();
- if (!handle_scope_implementer->CallDepthIsZero()) return;
- // Fire callbacks. Increase call depth to prevent recursive callbacks.
- handle_scope_implementer->IncrementCallDepth();
- if (run_microtasks) Execution::RunMicrotasks(isolate);
- if (has_call_completed_callbacks) {
- for (int i = 0; i < call_completed_callbacks_->length(); i++) {
- call_completed_callbacks_->at(i)();
- }
- }
- handle_scope_implementer->DecrementCallDepth();
-}
-
-
-void V8::RunMicrotasks(Isolate* isolate) {
- if (!isolate->microtask_pending())
- return;
-
- HandleScopeImplementer* handle_scope_implementer =
- isolate->handle_scope_implementer();
- ASSERT(handle_scope_implementer->CallDepthIsZero());
-
- // Increase call depth to prevent recursive callbacks.
- handle_scope_implementer->IncrementCallDepth();
- Execution::RunMicrotasks(isolate);
- handle_scope_implementer->DecrementCallDepth();
-}
-
-
void V8::InitializeOncePerProcessImpl() {
FlagList::EnforceFlagImplications();
+ Serializer::InitializeOncePerProcess();
if (FLAG_predictable && FLAG_random_seed == 0) {
// Avoid random seeds in predictable mode.
@@ -195,15 +99,23 @@ void V8::InitializeOncePerProcessImpl() {
if (FLAG_stress_compaction) {
FLAG_force_marking_deque_overflows = true;
FLAG_gc_global = true;
- FLAG_max_new_space_size = (1 << (kPageSizeBits - 10)) * 2;
+ FLAG_max_new_space_size = 2 * Page::kPageSize;
}
#ifdef V8_USE_DEFAULT_PLATFORM
platform_ = new DefaultPlatform;
#endif
Sampler::SetUp();
- CPU::SetUp();
+ // TODO(svenpanne) Clean this up when Serializer is a real object.
+ bool serializer_enabled = Serializer::enabled(NULL);
+ CpuFeatures::Probe(serializer_enabled);
OS::PostSetUp();
+ // The custom exp implementation needs 16KB of lookup data; initialize it
+ // on demand.
+ init_fast_sqrt_function();
+#ifdef _WIN64
+ init_modulo_function();
+#endif
ElementsAccessor::InitializeOncePerProcess();
LOperand::SetUpCaches();
SetUpJSCallerSavedCodeData();
diff --git a/deps/v8/src/v8.h b/deps/v8/src/v8.h
index d3f5a9c839..f019e68b7f 100644
--- a/deps/v8/src/v8.h
+++ b/deps/v8/src/v8.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
//
// Top include for all V8 .cc files.
@@ -55,7 +32,7 @@
#include "v8checks.h"
#include "allocation.h"
#include "assert-scope.h"
-#include "v8utils.h"
+#include "utils.h"
#include "flags.h"
// Objects & heap
@@ -66,6 +43,7 @@
#include "mark-compact-inl.h"
#include "log-inl.h"
#include "handles-inl.h"
+#include "types-inl.h"
#include "zone-inl.h"
namespace v8 {
@@ -97,12 +75,6 @@ class V8 : public AllStatic {
// Support for entry hooking JITed code.
static void SetFunctionEntryHook(FunctionEntryHook entry_hook);
- static void AddCallCompletedCallback(CallCompletedCallback callback);
- static void RemoveCallCompletedCallback(CallCompletedCallback callback);
- static void FireCallCompletedCallback(Isolate* isolate);
-
- static void RunMicrotasks(Isolate* isolate);
-
static v8::ArrayBuffer::Allocator* ArrayBufferAllocator() {
return array_buffer_allocator_;
}
@@ -120,8 +92,6 @@ class V8 : public AllStatic {
static void InitializeOncePerProcessImpl();
static void InitializeOncePerProcess();
- // List of callbacks when a Call completes.
- static List<CallCompletedCallback>* call_completed_callbacks_;
// Allocator for external array buffers.
static v8::ArrayBuffer::Allocator* array_buffer_allocator_;
// v8::Platform to use.
@@ -135,6 +105,4 @@ enum NilValue { kNullValue, kUndefinedValue };
} } // namespace v8::internal
-namespace i = v8::internal;
-
#endif // V8_V8_H_
diff --git a/deps/v8/src/v8checks.h b/deps/v8/src/v8checks.h
index 76e16fd24e..79a3088682 100644
--- a/deps/v8/src/v8checks.h
+++ b/deps/v8/src/v8checks.h
@@ -1,29 +1,6 @@
// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_V8CHECKS_H_
#define V8_V8CHECKS_H_
diff --git a/deps/v8/src/v8conversions.cc b/deps/v8/src/v8conversions.cc
deleted file mode 100644
index 900b62d10b..0000000000
--- a/deps/v8/src/v8conversions.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <stdarg.h>
-#include <limits.h>
-
-#include "v8.h"
-
-#include "conversions-inl.h"
-#include "v8conversions.h"
-#include "dtoa.h"
-#include "factory.h"
-#include "strtod.h"
-
-namespace v8 {
-namespace internal {
-
-namespace {
-
-// C++-style iterator adaptor for StringCharacterStream
-// (unlike C++ iterators the end-marker has different type).
-class StringCharacterStreamIterator {
- public:
- class EndMarker {};
-
- explicit StringCharacterStreamIterator(StringCharacterStream* stream);
-
- uint16_t operator*() const;
- void operator++();
- bool operator==(EndMarker const&) const { return end_; }
- bool operator!=(EndMarker const& m) const { return !end_; }
-
- private:
- StringCharacterStream* const stream_;
- uint16_t current_;
- bool end_;
-};
-
-
-StringCharacterStreamIterator::StringCharacterStreamIterator(
- StringCharacterStream* stream) : stream_(stream) {
- ++(*this);
-}
-
-uint16_t StringCharacterStreamIterator::operator*() const {
- return current_;
-}
-
-
-void StringCharacterStreamIterator::operator++() {
- end_ = !stream_->HasMore();
- if (!end_) {
- current_ = stream_->GetNext();
- }
-}
-} // End anonymous namespace.
-
-
-double StringToDouble(UnicodeCache* unicode_cache,
- String* str, int flags, double empty_string_val) {
- StringShape shape(str);
- // TODO(dcarney): Use a Visitor here.
- if (shape.IsSequentialAscii()) {
- const uint8_t* begin = SeqOneByteString::cast(str)->GetChars();
- const uint8_t* end = begin + str->length();
- return InternalStringToDouble(unicode_cache, begin, end, flags,
- empty_string_val);
- } else if (shape.IsSequentialTwoByte()) {
- const uc16* begin = SeqTwoByteString::cast(str)->GetChars();
- const uc16* end = begin + str->length();
- return InternalStringToDouble(unicode_cache, begin, end, flags,
- empty_string_val);
- } else {
- ConsStringIteratorOp op;
- StringCharacterStream stream(str, &op);
- return InternalStringToDouble(unicode_cache,
- StringCharacterStreamIterator(&stream),
- StringCharacterStreamIterator::EndMarker(),
- flags,
- empty_string_val);
- }
-}
-
-
-double StringToInt(UnicodeCache* unicode_cache,
- String* str,
- int radix) {
- StringShape shape(str);
- // TODO(dcarney): Use a Visitor here.
- if (shape.IsSequentialAscii()) {
- const uint8_t* begin = SeqOneByteString::cast(str)->GetChars();
- const uint8_t* end = begin + str->length();
- return InternalStringToInt(unicode_cache, begin, end, radix);
- } else if (shape.IsSequentialTwoByte()) {
- const uc16* begin = SeqTwoByteString::cast(str)->GetChars();
- const uc16* end = begin + str->length();
- return InternalStringToInt(unicode_cache, begin, end, radix);
- } else {
- ConsStringIteratorOp op;
- StringCharacterStream stream(str, &op);
- return InternalStringToInt(unicode_cache,
- StringCharacterStreamIterator(&stream),
- StringCharacterStreamIterator::EndMarker(),
- radix);
- }
-}
-
-} } // namespace v8::internal
diff --git a/deps/v8/src/v8conversions.h b/deps/v8/src/v8conversions.h
deleted file mode 100644
index f2568c066f..0000000000
--- a/deps/v8/src/v8conversions.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef V8_V8CONVERSIONS_H_
-#define V8_V8CONVERSIONS_H_
-
-#include "conversions.h"
-
-namespace v8 {
-namespace internal {
-
-
-static inline bool IsMinusZero(double value) {
- static const DoubleRepresentation minus_zero(-0.0);
- return DoubleRepresentation(value) == minus_zero;
-}
-
-
-// Integer32 is an integer that can be represented as a signed 32-bit
-// integer. It has to be in the range [-2^31, 2^31 - 1].
-// We also have to check for negative 0 as it is not an Integer32.
-static inline bool IsInt32Double(double value) {
- return !IsMinusZero(value) &&
- value >= kMinInt &&
- value <= kMaxInt &&
- value == FastI2D(FastD2I(value));
-}
-
-
-// Convert from Number object to C integer.
-inline int32_t NumberToInt32(Object* number) {
- if (number->IsSmi()) return Smi::cast(number)->value();
- return DoubleToInt32(number->Number());
-}
-
-
-inline uint32_t NumberToUint32(Object* number) {
- if (number->IsSmi()) return Smi::cast(number)->value();
- return DoubleToUint32(number->Number());
-}
-
-
-// Converts a string into a double value according to ECMA-262 9.3.1
-double StringToDouble(UnicodeCache* unicode_cache,
- String* str,
- int flags,
- double empty_string_val = 0);
-
-// Converts a string into an integer.
-double StringToInt(UnicodeCache* unicode_cache, String* str, int radix);
-
-inline bool TryNumberToSize(Isolate* isolate,
- Object* number, size_t* result) {
- SealHandleScope shs(isolate);
- if (number->IsSmi()) {
- int value = Smi::cast(number)->value();
- ASSERT(
- static_cast<unsigned>(Smi::kMaxValue)
- <= std::numeric_limits<size_t>::max());
- if (value >= 0) {
- *result = static_cast<size_t>(value);
- return true;
- }
- return false;
- } else {
- ASSERT(number->IsHeapNumber());
- double value = HeapNumber::cast(number)->value();
- if (value >= 0 &&
- value <= std::numeric_limits<size_t>::max()) {
- *result = static_cast<size_t>(value);
- return true;
- } else {
- return false;
- }
- }
-}
-
-// Converts a number into size_t.
-inline size_t NumberToSize(Isolate* isolate,
- Object* number) {
- size_t result = 0;
- bool is_valid = TryNumberToSize(isolate, number, &result);
- CHECK(is_valid);
- return result;
-}
-
-} } // namespace v8::internal
-
-#endif // V8_V8CONVERSIONS_H_
diff --git a/deps/v8/src/v8dll-main.cc b/deps/v8/src/v8dll-main.cc
index 7f6c9f955d..dd08569026 100644
--- a/deps/v8/src/v8dll-main.cc
+++ b/deps/v8/src/v8dll-main.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// The GYP based build ends up defining USING_V8_SHARED when compiling this
// file.
diff --git a/deps/v8/src/v8globals.h b/deps/v8/src/v8globals.h
index e6cd94df23..b9ca952e75 100644
--- a/deps/v8/src/v8globals.h
+++ b/deps/v8/src/v8globals.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_V8GLOBALS_H_
#define V8_V8GLOBALS_H_
@@ -59,6 +36,7 @@ const intptr_t kCodeAlignment = 1 << kCodeAlignmentBits;
const intptr_t kCodeAlignmentMask = kCodeAlignment - 1;
// Tag information for Failure.
+// TODO(yangguo): remove this from space owner calculation.
const int kFailureTag = 3;
const int kFailureTagSize = 2;
const intptr_t kFailureTagMask = (1 << kFailureTagSize) - 1;
@@ -128,6 +106,7 @@ class MemoryChunk;
class SeededNumberDictionary;
class UnseededNumberDictionary;
class NameDictionary;
+template <typename T> class MaybeHandle;
template <typename T> class Handle;
class Heap;
class HeapObject;
@@ -146,7 +125,6 @@ class MapSpace;
class MarkCompactCollector;
class NewSpace;
class Object;
-class MaybeObject;
class OldSpace;
class Foreign;
class Scope;
@@ -184,6 +162,7 @@ enum AllocationSpace {
CELL_SPACE, // Only and all cell objects.
PROPERTY_CELL_SPACE, // Only and all global property cell objects.
LO_SPACE, // Promoted large objects.
+ INVALID_SPACE, // Only used in AllocationResult to signal success.
FIRST_SPACE = NEW_SPACE,
LAST_SPACE = LO_SPACE,
@@ -282,8 +261,6 @@ enum InlineCacheState {
enum CallFunctionFlags {
NO_CALL_FUNCTION_FLAGS,
- // The call target is cached in the instruction stream.
- RECORD_CALL_TARGET,
CALL_AS_METHOD,
// Always wrap the receiver and call to the JSFunction. Only use this flag
// both the receiver type and the target method are statically known.
@@ -291,6 +268,13 @@ enum CallFunctionFlags {
};
+enum CallConstructorFlags {
+ NO_CALL_CONSTRUCTOR_FLAGS,
+ // The call target is cached in the instruction stream.
+ RECORD_CONSTRUCTOR_TARGET
+};
+
+
enum InlineCacheHolderFlag {
OWN_MAP, // For fast properties objects.
PROTOTYPE_MAP // For slow properties objects (except GlobalObjects).
@@ -348,8 +332,8 @@ union IeeeDoubleBigEndianArchType {
// AccessorCallback
struct AccessorDescriptor {
- MaybeObject* (*getter)(Isolate* isolate, Object* object, void* data);
- MaybeObject* (*setter)(
+ Object* (*getter)(Isolate* isolate, Object* object, void* data);
+ Object* (*setter)(
Isolate* isolate, JSObject* object, Object* value, void* data);
void* data;
};
@@ -565,4 +549,6 @@ enum MinusZeroMode {
} } // namespace v8::internal
+namespace i = v8::internal;
+
#endif // V8_V8GLOBALS_H_
diff --git a/deps/v8/src/v8memory.h b/deps/v8/src/v8memory.h
index c72ce7ab7b..615ec4fe87 100644
--- a/deps/v8/src/v8memory.h
+++ b/deps/v8/src/v8memory.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_MEMORY_H_
#define V8_MEMORY_H_
diff --git a/deps/v8/src/v8natives.js b/deps/v8/src/v8natives.js
index f183afb968..cd60cb40d8 100644
--- a/deps/v8/src/v8natives.js
+++ b/deps/v8/src/v8natives.js
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file relies on the fact that the following declarations have been made
// in runtime.js:
@@ -1893,14 +1870,6 @@ SetUpFunction();
// Eventually, we should move to a real event queue that allows to maintain
// relative ordering of different kinds of tasks.
-function GetMicrotaskQueue() {
- var microtaskState = %GetMicrotaskState();
- if (IS_UNDEFINED(microtaskState.queue)) {
- microtaskState.queue = new InternalArray;
- }
- return microtaskState.queue;
-}
-
function RunMicrotasks() {
while (%SetMicrotaskPending(false)) {
var microtaskState = %GetMicrotaskState();
@@ -1908,7 +1877,7 @@ function RunMicrotasks() {
return;
var microtasks = microtaskState.queue;
- microtaskState.queue = new InternalArray;
+ microtaskState.queue = null;
for (var i = 0; i < microtasks.length; i++) {
microtasks[i]();
@@ -1916,7 +1885,11 @@ function RunMicrotasks() {
}
}
-function EnqueueExternalMicrotask(fn) {
- GetMicrotaskQueue().push(fn);
+function EnqueueMicrotask(fn) {
+ var microtaskState = %GetMicrotaskState();
+ if (IS_UNDEFINED(microtaskState.queue) || IS_NULL(microtaskState.queue)) {
+ microtaskState.queue = new InternalArray;
+ }
+ microtaskState.queue.push(fn);
%SetMicrotaskPending(true);
}
diff --git a/deps/v8/src/v8threads.cc b/deps/v8/src/v8threads.cc
index 1de9d4fd76..410d0b133c 100644
--- a/deps/v8/src/v8threads.cc
+++ b/deps/v8/src/v8threads.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -74,10 +51,6 @@ void Locker::Initialize(v8::Isolate* isolate) {
isolate_->stack_guard()->ClearThread(access);
isolate_->stack_guard()->InitThread(access);
}
- if (isolate_->IsDefaultIsolate()) {
- // This only enters if not yet entered.
- internal::Isolate::EnterDefaultIsolate();
- }
}
ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread());
}
@@ -98,9 +71,6 @@ bool Locker::IsActive() {
Locker::~Locker() {
ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread());
if (has_lock_) {
- if (isolate_->IsDefaultIsolate()) {
- isolate_->Exit();
- }
if (top_level_) {
isolate_->thread_manager()->FreeThreadResources();
} else {
@@ -115,9 +85,6 @@ void Unlocker::Initialize(v8::Isolate* isolate) {
ASSERT(isolate != NULL);
isolate_ = reinterpret_cast<i::Isolate*>(isolate);
ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread());
- if (isolate_->IsDefaultIsolate()) {
- isolate_->Exit();
- }
isolate_->thread_manager()->ArchiveThread();
isolate_->thread_manager()->Unlock();
}
@@ -127,9 +94,6 @@ Unlocker::~Unlocker() {
ASSERT(!isolate_->thread_manager()->IsLockedByCurrentThread());
isolate_->thread_manager()->Lock();
isolate_->thread_manager()->RestoreThread();
- if (isolate_->IsDefaultIsolate()) {
- isolate_->Enter();
- }
}
@@ -175,9 +139,7 @@ bool ThreadManager::RestoreThread() {
from = isolate_->handle_scope_implementer()->RestoreThread(from);
from = isolate_->RestoreThread(from);
from = Relocatable::RestoreState(isolate_, from);
-#ifdef ENABLE_DEBUGGER_SUPPORT
from = isolate_->debug()->RestoreDebug(from);
-#endif
from = isolate_->stack_guard()->RestoreStackGuard(from);
from = isolate_->regexp_stack()->RestoreStack(from);
from = isolate_->bootstrapper()->RestoreState(from);
@@ -209,9 +171,7 @@ void ThreadManager::Unlock() {
static int ArchiveSpacePerThread() {
return HandleScopeImplementer::ArchiveSpacePerThread() +
Isolate::ArchiveSpacePerThread() +
-#ifdef ENABLE_DEBUGGER_SUPPORT
Debug::ArchiveSpacePerThread() +
-#endif
StackGuard::ArchiveSpacePerThread() +
RegExpStack::ArchiveSpacePerThread() +
Bootstrapper::ArchiveSpacePerThread() +
@@ -337,9 +297,7 @@ void ThreadManager::EagerlyArchiveThread() {
to = isolate_->handle_scope_implementer()->ArchiveThread(to);
to = isolate_->ArchiveThread(to);
to = Relocatable::ArchiveState(isolate_, to);
-#ifdef ENABLE_DEBUGGER_SUPPORT
to = isolate_->debug()->ArchiveDebug(to);
-#endif
to = isolate_->stack_guard()->ArchiveStackGuard(to);
to = isolate_->regexp_stack()->ArchiveStack(to);
to = isolate_->bootstrapper()->ArchiveState(to);
@@ -351,9 +309,7 @@ void ThreadManager::EagerlyArchiveThread() {
void ThreadManager::FreeThreadResources() {
isolate_->handle_scope_implementer()->FreeThreadResources();
isolate_->FreeThreadResources();
-#ifdef ENABLE_DEBUGGER_SUPPORT
isolate_->debug()->FreeThreadResources();
-#endif
isolate_->stack_guard()->FreeThreadResources();
isolate_->regexp_stack()->FreeThreadResources();
isolate_->bootstrapper()->FreeThreadResources();
diff --git a/deps/v8/src/v8threads.h b/deps/v8/src/v8threads.h
index a20700a5c9..ca722adc66 100644
--- a/deps/v8/src/v8threads.h
+++ b/deps/v8/src/v8threads.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_V8THREADS_H_
#define V8_V8THREADS_H_
diff --git a/deps/v8/src/v8utils.cc b/deps/v8/src/v8utils.cc
deleted file mode 100644
index 7390d854e6..0000000000
--- a/deps/v8/src/v8utils.cc
+++ /dev/null
@@ -1,276 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <stdarg.h>
-
-#include "v8.h"
-
-#include "platform.h"
-
-#include "sys/stat.h"
-
-namespace v8 {
-namespace internal {
-
-
-void PrintF(const char* format, ...) {
- va_list arguments;
- va_start(arguments, format);
- OS::VPrint(format, arguments);
- va_end(arguments);
-}
-
-
-void PrintF(FILE* out, const char* format, ...) {
- va_list arguments;
- va_start(arguments, format);
- OS::VFPrint(out, format, arguments);
- va_end(arguments);
-}
-
-
-void PrintPID(const char* format, ...) {
- OS::Print("[%d] ", OS::GetCurrentProcessId());
- va_list arguments;
- va_start(arguments, format);
- OS::VPrint(format, arguments);
- va_end(arguments);
-}
-
-
-void Flush(FILE* out) {
- fflush(out);
-}
-
-
-char* ReadLine(const char* prompt) {
- char* result = NULL;
- char line_buf[256];
- int offset = 0;
- bool keep_going = true;
- fprintf(stdout, "%s", prompt);
- fflush(stdout);
- while (keep_going) {
- if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
- // fgets got an error. Just give up.
- if (result != NULL) {
- DeleteArray(result);
- }
- return NULL;
- }
- int len = StrLength(line_buf);
- if (len > 1 &&
- line_buf[len - 2] == '\\' &&
- line_buf[len - 1] == '\n') {
- // When we read a line that ends with a "\" we remove the escape and
- // append the remainder.
- line_buf[len - 2] = '\n';
- line_buf[len - 1] = 0;
- len -= 1;
- } else if ((len > 0) && (line_buf[len - 1] == '\n')) {
- // Since we read a new line we are done reading the line. This
- // will exit the loop after copying this buffer into the result.
- keep_going = false;
- }
- if (result == NULL) {
- // Allocate the initial result and make room for the terminating '\0'
- result = NewArray<char>(len + 1);
- } else {
- // Allocate a new result with enough room for the new addition.
- int new_len = offset + len + 1;
- char* new_result = NewArray<char>(new_len);
- // Copy the existing input into the new array and set the new
- // array as the result.
- OS::MemCopy(new_result, result, offset * kCharSize);
- DeleteArray(result);
- result = new_result;
- }
- // Copy the newly read line into the result.
- OS::MemCopy(result + offset, line_buf, len * kCharSize);
- offset += len;
- }
- ASSERT(result != NULL);
- result[offset] = '\0';
- return result;
-}
-
-
-char* ReadCharsFromFile(FILE* file,
- int* size,
- int extra_space,
- bool verbose,
- const char* filename) {
- if (file == NULL || fseek(file, 0, SEEK_END) != 0) {
- if (verbose) {
- OS::PrintError("Cannot read from file %s.\n", filename);
- }
- return NULL;
- }
-
- // Get the size of the file and rewind it.
- *size = ftell(file);
- rewind(file);
-
- char* result = NewArray<char>(*size + extra_space);
- for (int i = 0; i < *size && feof(file) == 0;) {
- int read = static_cast<int>(fread(&result[i], 1, *size - i, file));
- if (read != (*size - i) && ferror(file) != 0) {
- fclose(file);
- DeleteArray(result);
- return NULL;
- }
- i += read;
- }
- return result;
-}
-
-
-char* ReadCharsFromFile(const char* filename,
- int* size,
- int extra_space,
- bool verbose) {
- FILE* file = OS::FOpen(filename, "rb");
- char* result = ReadCharsFromFile(file, size, extra_space, verbose, filename);
- if (file != NULL) fclose(file);
- return result;
-}
-
-
-byte* ReadBytes(const char* filename, int* size, bool verbose) {
- char* chars = ReadCharsFromFile(filename, size, 0, verbose);
- return reinterpret_cast<byte*>(chars);
-}
-
-
-static Vector<const char> SetVectorContents(char* chars,
- int size,
- bool* exists) {
- if (!chars) {
- *exists = false;
- return Vector<const char>::empty();
- }
- chars[size] = '\0';
- *exists = true;
- return Vector<const char>(chars, size);
-}
-
-
-Vector<const char> ReadFile(const char* filename,
- bool* exists,
- bool verbose) {
- int size;
- char* result = ReadCharsFromFile(filename, &size, 1, verbose);
- return SetVectorContents(result, size, exists);
-}
-
-
-Vector<const char> ReadFile(FILE* file,
- bool* exists,
- bool verbose) {
- int size;
- char* result = ReadCharsFromFile(file, &size, 1, verbose, "");
- return SetVectorContents(result, size, exists);
-}
-
-
-int WriteCharsToFile(const char* str, int size, FILE* f) {
- int total = 0;
- while (total < size) {
- int write = static_cast<int>(fwrite(str, 1, size - total, f));
- if (write == 0) {
- return total;
- }
- total += write;
- str += write;
- }
- return total;
-}
-
-
-int AppendChars(const char* filename,
- const char* str,
- int size,
- bool verbose) {
- FILE* f = OS::FOpen(filename, "ab");
- if (f == NULL) {
- if (verbose) {
- OS::PrintError("Cannot open file %s for writing.\n", filename);
- }
- return 0;
- }
- int written = WriteCharsToFile(str, size, f);
- fclose(f);
- return written;
-}
-
-
-int WriteChars(const char* filename,
- const char* str,
- int size,
- bool verbose) {
- FILE* f = OS::FOpen(filename, "wb");
- if (f == NULL) {
- if (verbose) {
- OS::PrintError("Cannot open file %s for writing.\n", filename);
- }
- return 0;
- }
- int written = WriteCharsToFile(str, size, f);
- fclose(f);
- return written;
-}
-
-
-int WriteBytes(const char* filename,
- const byte* bytes,
- int size,
- bool verbose) {
- const char* str = reinterpret_cast<const char*>(bytes);
- return WriteChars(filename, str, size, verbose);
-}
-
-
-
-void StringBuilder::AddFormatted(const char* format, ...) {
- va_list arguments;
- va_start(arguments, format);
- AddFormattedList(format, arguments);
- va_end(arguments);
-}
-
-
-void StringBuilder::AddFormattedList(const char* format, va_list list) {
- ASSERT(!is_finalized() && position_ <= buffer_.length());
- int n = OS::VSNPrintF(buffer_ + position_, format, list);
- if (n < 0 || n >= (buffer_.length() - position_)) {
- position_ = buffer_.length();
- } else {
- position_ += n;
- }
-}
-
-} } // namespace v8::internal
diff --git a/deps/v8/src/v8utils.h b/deps/v8/src/v8utils.h
deleted file mode 100644
index 058b153a7e..0000000000
--- a/deps/v8/src/v8utils.h
+++ /dev/null
@@ -1,464 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef V8_V8UTILS_H_
-#define V8_V8UTILS_H_
-
-#include "utils.h"
-#include "platform.h" // For va_list on Solaris.
-
-namespace v8 {
-namespace internal {
-
-// ----------------------------------------------------------------------------
-// I/O support.
-
-#if __GNUC__ >= 4
-// On gcc we can ask the compiler to check the types of %d-style format
-// specifiers and their associated arguments. TODO(erikcorry) fix this
-// so it works on MacOSX.
-#if defined(__MACH__) && defined(__APPLE__)
-#define PRINTF_CHECKING
-#define FPRINTF_CHECKING
-#else // MacOsX.
-#define PRINTF_CHECKING __attribute__ ((format (printf, 1, 2)))
-#define FPRINTF_CHECKING __attribute__ ((format (printf, 2, 3)))
-#endif
-#else
-#define PRINTF_CHECKING
-#define FPRINTF_CHECKING
-#endif
-
-// Our version of printf().
-void PRINTF_CHECKING PrintF(const char* format, ...);
-void FPRINTF_CHECKING PrintF(FILE* out, const char* format, ...);
-
-// Prepends the current process ID to the output.
-void PRINTF_CHECKING PrintPID(const char* format, ...);
-
-// Our version of fflush.
-void Flush(FILE* out);
-
-inline void Flush() {
- Flush(stdout);
-}
-
-
-// Read a line of characters after printing the prompt to stdout. The resulting
-// char* needs to be disposed off with DeleteArray by the caller.
-char* ReadLine(const char* prompt);
-
-
-// Read and return the raw bytes in a file. the size of the buffer is returned
-// in size.
-// The returned buffer must be freed by the caller.
-byte* ReadBytes(const char* filename, int* size, bool verbose = true);
-
-
-// Append size chars from str to the file given by filename.
-// The file is overwritten. Returns the number of chars written.
-int AppendChars(const char* filename,
- const char* str,
- int size,
- bool verbose = true);
-
-
-// Write size chars from str to the file given by filename.
-// The file is overwritten. Returns the number of chars written.
-int WriteChars(const char* filename,
- const char* str,
- int size,
- bool verbose = true);
-
-
-// Write size bytes to the file given by filename.
-// The file is overwritten. Returns the number of bytes written.
-int WriteBytes(const char* filename,
- const byte* bytes,
- int size,
- bool verbose = true);
-
-
-// Write the C code
-// const char* <varname> = "<str>";
-// const int <varname>_len = <len>;
-// to the file given by filename. Only the first len chars are written.
-int WriteAsCFile(const char* filename, const char* varname,
- const char* str, int size, bool verbose = true);
-
-
-// ----------------------------------------------------------------------------
-// Data structures
-
-template <typename T>
-inline Vector< Handle<Object> > HandleVector(v8::internal::Handle<T>* elms,
- int length) {
- return Vector< Handle<Object> >(
- reinterpret_cast<v8::internal::Handle<Object>*>(elms), length);
-}
-
-
-// ----------------------------------------------------------------------------
-// Memory
-
-// Copies words from |src| to |dst|. The data spans must not overlap.
-template <typename T>
-inline void CopyWords(T* dst, const T* src, size_t num_words) {
- STATIC_ASSERT(sizeof(T) == kPointerSize);
- ASSERT(Min(dst, const_cast<T*>(src)) + num_words <=
- Max(dst, const_cast<T*>(src)));
- ASSERT(num_words > 0);
-
- // Use block copying OS::MemCopy if the segment we're copying is
- // enough to justify the extra call/setup overhead.
- static const size_t kBlockCopyLimit = 16;
-
- if (num_words < kBlockCopyLimit) {
- do {
- num_words--;
- *dst++ = *src++;
- } while (num_words > 0);
- } else {
- OS::MemCopy(dst, src, num_words * kPointerSize);
- }
-}
-
-
-// Copies words from |src| to |dst|. No restrictions.
-template <typename T>
-inline void MoveWords(T* dst, const T* src, size_t num_words) {
- STATIC_ASSERT(sizeof(T) == kPointerSize);
- ASSERT(num_words > 0);
-
- // Use block copying OS::MemCopy if the segment we're copying is
- // enough to justify the extra call/setup overhead.
- static const size_t kBlockCopyLimit = 16;
-
- if (num_words < kBlockCopyLimit &&
- ((dst < src) || (dst >= (src + num_words * kPointerSize)))) {
- T* end = dst + num_words;
- do {
- num_words--;
- *dst++ = *src++;
- } while (num_words > 0);
- } else {
- OS::MemMove(dst, src, num_words * kPointerSize);
- }
-}
-
-
-// Copies data from |src| to |dst|. The data spans must not overlap.
-template <typename T>
-inline void CopyBytes(T* dst, const T* src, size_t num_bytes) {
- STATIC_ASSERT(sizeof(T) == 1);
- ASSERT(Min(dst, const_cast<T*>(src)) + num_bytes <=
- Max(dst, const_cast<T*>(src)));
- if (num_bytes == 0) return;
-
- // Use block copying OS::MemCopy if the segment we're copying is
- // enough to justify the extra call/setup overhead.
- static const int kBlockCopyLimit = OS::kMinComplexMemCopy;
-
- if (num_bytes < static_cast<size_t>(kBlockCopyLimit)) {
- do {
- num_bytes--;
- *dst++ = *src++;
- } while (num_bytes > 0);
- } else {
- OS::MemCopy(dst, src, num_bytes);
- }
-}
-
-
-template <typename T, typename U>
-inline void MemsetPointer(T** dest, U* value, int counter) {
-#ifdef DEBUG
- T* a = NULL;
- U* b = NULL;
- a = b; // Fake assignment to check assignability.
- USE(a);
-#endif // DEBUG
-#if V8_HOST_ARCH_IA32
-#define STOS "stosl"
-#elif V8_HOST_ARCH_X64
-#define STOS "stosq"
-#endif
-#if defined(__native_client__)
- // This STOS sequence does not validate for x86_64 Native Client.
- // Here we #undef STOS to force use of the slower C version.
- // TODO(bradchen): Profile V8 and implement a faster REP STOS
- // here if the profile indicates it matters.
-#undef STOS
-#endif
-
-#if defined(__GNUC__) && defined(STOS)
- asm volatile(
- "cld;"
- "rep ; " STOS
- : "+&c" (counter), "+&D" (dest)
- : "a" (value)
- : "memory", "cc");
-#else
- for (int i = 0; i < counter; i++) {
- dest[i] = value;
- }
-#endif
-
-#undef STOS
-}
-
-
-// Simple wrapper that allows an ExternalString to refer to a
-// Vector<const char>. Doesn't assume ownership of the data.
-class AsciiStringAdapter: public v8::String::ExternalAsciiStringResource {
- public:
- explicit AsciiStringAdapter(Vector<const char> data) : data_(data) {}
-
- virtual const char* data() const { return data_.start(); }
-
- virtual size_t length() const { return data_.length(); }
-
- private:
- Vector<const char> data_;
-};
-
-
-// Simple support to read a file into a 0-terminated C-string.
-// The returned buffer must be freed by the caller.
-// On return, *exits tells whether the file existed.
-Vector<const char> ReadFile(const char* filename,
- bool* exists,
- bool verbose = true);
-Vector<const char> ReadFile(FILE* file,
- bool* exists,
- bool verbose = true);
-
-
-template <typename sourcechar, typename sinkchar>
-INLINE(static void CopyCharsUnsigned(sinkchar* dest,
- const sourcechar* src,
- int chars));
-#if defined(V8_HOST_ARCH_ARM)
-INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars));
-INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars));
-INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars));
-#elif defined(V8_HOST_ARCH_MIPS)
-INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars));
-INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars));
-#endif
-
-// Copy from ASCII/16bit chars to ASCII/16bit chars.
-template <typename sourcechar, typename sinkchar>
-INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, int chars));
-
-template<typename sourcechar, typename sinkchar>
-void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
- ASSERT(sizeof(sourcechar) <= 2);
- ASSERT(sizeof(sinkchar) <= 2);
- if (sizeof(sinkchar) == 1) {
- if (sizeof(sourcechar) == 1) {
- CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
- reinterpret_cast<const uint8_t*>(src),
- chars);
- } else {
- CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
- reinterpret_cast<const uint16_t*>(src),
- chars);
- }
- } else {
- if (sizeof(sourcechar) == 1) {
- CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
- reinterpret_cast<const uint8_t*>(src),
- chars);
- } else {
- CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
- reinterpret_cast<const uint16_t*>(src),
- chars);
- }
- }
-}
-
-template <typename sourcechar, typename sinkchar>
-void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, int chars) {
- sinkchar* limit = dest + chars;
-#ifdef V8_HOST_CAN_READ_UNALIGNED
- if (sizeof(*dest) == sizeof(*src)) {
- if (chars >= static_cast<int>(OS::kMinComplexMemCopy / sizeof(*dest))) {
- OS::MemCopy(dest, src, chars * sizeof(*dest));
- return;
- }
- // Number of characters in a uintptr_t.
- static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest); // NOLINT
- ASSERT(dest + kStepSize > dest); // Check for overflow.
- while (dest + kStepSize <= limit) {
- *reinterpret_cast<uintptr_t*>(dest) =
- *reinterpret_cast<const uintptr_t*>(src);
- dest += kStepSize;
- src += kStepSize;
- }
- }
-#endif
- while (dest < limit) {
- *dest++ = static_cast<sinkchar>(*src++);
- }
-}
-
-
-#if defined(V8_HOST_ARCH_ARM)
-void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
- switch (static_cast<unsigned>(chars)) {
- case 0:
- break;
- case 1:
- *dest = *src;
- break;
- case 2:
- memcpy(dest, src, 2);
- break;
- case 3:
- memcpy(dest, src, 3);
- break;
- case 4:
- memcpy(dest, src, 4);
- break;
- case 5:
- memcpy(dest, src, 5);
- break;
- case 6:
- memcpy(dest, src, 6);
- break;
- case 7:
- memcpy(dest, src, 7);
- break;
- case 8:
- memcpy(dest, src, 8);
- break;
- case 9:
- memcpy(dest, src, 9);
- break;
- case 10:
- memcpy(dest, src, 10);
- break;
- case 11:
- memcpy(dest, src, 11);
- break;
- case 12:
- memcpy(dest, src, 12);
- break;
- case 13:
- memcpy(dest, src, 13);
- break;
- case 14:
- memcpy(dest, src, 14);
- break;
- case 15:
- memcpy(dest, src, 15);
- break;
- default:
- OS::MemCopy(dest, src, chars);
- break;
- }
-}
-
-
-void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars) {
- if (chars >= OS::kMinComplexConvertMemCopy) {
- OS::MemCopyUint16Uint8(dest, src, chars);
- } else {
- OS::MemCopyUint16Uint8Wrapper(dest, src, chars);
- }
-}
-
-
-void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
- switch (static_cast<unsigned>(chars)) {
- case 0:
- break;
- case 1:
- *dest = *src;
- break;
- case 2:
- memcpy(dest, src, 4);
- break;
- case 3:
- memcpy(dest, src, 6);
- break;
- case 4:
- memcpy(dest, src, 8);
- break;
- case 5:
- memcpy(dest, src, 10);
- break;
- case 6:
- memcpy(dest, src, 12);
- break;
- case 7:
- memcpy(dest, src, 14);
- break;
- default:
- OS::MemCopy(dest, src, chars * sizeof(*dest));
- break;
- }
-}
-
-
-#elif defined(V8_HOST_ARCH_MIPS)
-void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
- if (chars < OS::kMinComplexMemCopy) {
- memcpy(dest, src, chars);
- } else {
- OS::MemCopy(dest, src, chars);
- }
-}
-
-void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
- if (chars < OS::kMinComplexMemCopy) {
- memcpy(dest, src, chars * sizeof(*dest));
- } else {
- OS::MemCopy(dest, src, chars * sizeof(*dest));
- }
-}
-#endif
-
-
-class StringBuilder : public SimpleStringBuilder {
- public:
- explicit StringBuilder(int size) : SimpleStringBuilder(size) { }
- StringBuilder(char* buffer, int size) : SimpleStringBuilder(buffer, size) { }
-
- // Add formatted contents to the builder just like printf().
- void AddFormatted(const char* format, ...);
-
- // Add formatted contents like printf based on a va_list.
- void AddFormattedList(const char* format, va_list list);
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
-};
-
-} } // namespace v8::internal
-
-#endif // V8_V8UTILS_H_
diff --git a/deps/v8/src/variables.cc b/deps/v8/src/variables.cc
index 6c4ea527ca..3b90e0eeac 100644
--- a/deps/v8/src/variables.cc
+++ b/deps/v8/src/variables.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -58,7 +35,7 @@ const char* Variable::Mode2String(VariableMode mode) {
Variable::Variable(Scope* scope,
Handle<String> name,
VariableMode mode,
- bool is_valid_LHS,
+ bool is_valid_ref,
Kind kind,
InitializationFlag initialization_flag,
Interface* interface)
@@ -70,7 +47,7 @@ Variable::Variable(Scope* scope,
index_(-1),
initializer_position_(RelocInfo::kNoPosition),
local_if_not_shadowed_(NULL),
- is_valid_LHS_(is_valid_LHS),
+ is_valid_ref_(is_valid_ref),
force_context_allocation_(false),
is_used_(false),
initialization_flag_(initialization_flag),
diff --git a/deps/v8/src/variables.h b/deps/v8/src/variables.h
index 401d044463..3d8e130d33 100644
--- a/deps/v8/src/variables.h
+++ b/deps/v8/src/variables.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_VARIABLES_H_
#define V8_VARIABLES_H_
@@ -77,7 +54,7 @@ class Variable: public ZoneObject {
Variable(Scope* scope,
Handle<String> name,
VariableMode mode,
- bool is_valid_lhs,
+ bool is_valid_ref,
Kind kind,
InitializationFlag initialization_flag,
Interface* interface = Interface::NewValue());
@@ -85,7 +62,7 @@ class Variable: public ZoneObject {
// Printing support
static const char* Mode2String(VariableMode mode);
- bool IsValidLeftHandSide() { return is_valid_LHS_; }
+ bool IsValidReference() { return is_valid_ref_; }
// The source code for an eval() call may refer to a variable that is
// in an outer scope about which we don't know anything (it may not
@@ -172,8 +149,8 @@ class Variable: public ZoneObject {
// binding scope (exclusive).
Variable* local_if_not_shadowed_;
- // Valid as a LHS? (const and this are not valid LHS, for example)
- bool is_valid_LHS_;
+ // Valid as a reference? (const and this are not valid, for example)
+ bool is_valid_ref_;
// Usage info.
bool force_context_allocation_; // set by variable resolver
diff --git a/deps/v8/src/vector.h b/deps/v8/src/vector.h
new file mode 100644
index 0000000000..9e8c200ed4
--- /dev/null
+++ b/deps/v8/src/vector.h
@@ -0,0 +1,171 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_VECTOR_H_
+#define V8_VECTOR_H_
+
+#include <string.h>
+#include <algorithm>
+
+#include "allocation.h"
+#include "checks.h"
+#include "globals.h"
+
+namespace v8 {
+namespace internal {
+
+
+template <typename T>
+class Vector {
+ public:
+ Vector() : start_(NULL), length_(0) {}
+ Vector(T* data, int length) : start_(data), length_(length) {
+ ASSERT(length == 0 || (length > 0 && data != NULL));
+ }
+
+ static Vector<T> New(int length) {
+ return Vector<T>(NewArray<T>(length), length);
+ }
+
+ // Returns a vector using the same backing storage as this one,
+ // spanning from and including 'from', to but not including 'to'.
+ Vector<T> SubVector(int from, int to) {
+ SLOW_ASSERT(to <= length_);
+ SLOW_ASSERT(from < to);
+ ASSERT(0 <= from);
+ return Vector<T>(start() + from, to - from);
+ }
+
+ // Returns the length of the vector.
+ int length() const { return length_; }
+
+ // Returns whether or not the vector is empty.
+ bool is_empty() const { return length_ == 0; }
+
+ // Returns the pointer to the start of the data in the vector.
+ T* start() const { return start_; }
+
+ // Access individual vector elements - checks bounds in debug mode.
+ T& operator[](int index) const {
+ ASSERT(0 <= index && index < length_);
+ return start_[index];
+ }
+
+ const T& at(int index) const { return operator[](index); }
+
+ T& first() { return start_[0]; }
+
+ T& last() { return start_[length_ - 1]; }
+
+ // Returns a clone of this vector with a new backing store.
+ Vector<T> Clone() const {
+ T* result = NewArray<T>(length_);
+ for (int i = 0; i < length_; i++) result[i] = start_[i];
+ return Vector<T>(result, length_);
+ }
+
+ void Sort(int (*cmp)(const T*, const T*)) {
+ std::sort(start(), start() + length(), RawComparer(cmp));
+ }
+
+ void Sort() {
+ std::sort(start(), start() + length());
+ }
+
+ void Truncate(int length) {
+ ASSERT(length <= length_);
+ length_ = length;
+ }
+
+ // Releases the array underlying this vector. Once disposed the
+ // vector is empty.
+ void Dispose() {
+ DeleteArray(start_);
+ start_ = NULL;
+ length_ = 0;
+ }
+
+ inline Vector<T> operator+(int offset) {
+ ASSERT(offset < length_);
+ return Vector<T>(start_ + offset, length_ - offset);
+ }
+
+ // Factory method for creating empty vectors.
+ static Vector<T> empty() { return Vector<T>(NULL, 0); }
+
+ template<typename S>
+ static Vector<T> cast(Vector<S> input) {
+ return Vector<T>(reinterpret_cast<T*>(input.start()),
+ input.length() * sizeof(S) / sizeof(T));
+ }
+
+ protected:
+ void set_start(T* start) { start_ = start; }
+
+ private:
+ T* start_;
+ int length_;
+
+ class RawComparer {
+ public:
+ explicit RawComparer(int (*cmp)(const T*, const T*)) : cmp_(cmp) {}
+ bool operator()(const T& a, const T& b) {
+ return cmp_(&a, &b) < 0;
+ }
+
+ private:
+ int (*cmp_)(const T*, const T*);
+ };
+};
+
+
+template <typename T>
+class ScopedVector : public Vector<T> {
+ public:
+ explicit ScopedVector(int length) : Vector<T>(NewArray<T>(length), length) { }
+ ~ScopedVector() {
+ DeleteArray(this->start());
+ }
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedVector);
+};
+
+
+inline int StrLength(const char* string) {
+ size_t length = strlen(string);
+ ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
+ return static_cast<int>(length);
+}
+
+
+#define STATIC_ASCII_VECTOR(x) \
+ v8::internal::Vector<const uint8_t>(reinterpret_cast<const uint8_t*>(x), \
+ ARRAY_SIZE(x)-1)
+
+inline Vector<const char> CStrVector(const char* data) {
+ return Vector<const char>(data, StrLength(data));
+}
+
+inline Vector<const uint8_t> OneByteVector(const char* data, int length) {
+ return Vector<const uint8_t>(reinterpret_cast<const uint8_t*>(data), length);
+}
+
+inline Vector<const uint8_t> OneByteVector(const char* data) {
+ return OneByteVector(data, StrLength(data));
+}
+
+inline Vector<char> MutableCStrVector(char* data) {
+ return Vector<char>(data, StrLength(data));
+}
+
+inline Vector<char> MutableCStrVector(char* data, int max) {
+ int length = StrLength(data);
+ return Vector<char>(data, (length < max) ? length : max);
+}
+
+
+} } // namespace v8::internal
+
+#endif // V8_VECTOR_H_
diff --git a/deps/v8/src/version.cc b/deps/v8/src/version.cc
index 904b067a6a..33755eb1fd 100644
--- a/deps/v8/src/version.cc
+++ b/deps/v8/src/version.cc
@@ -33,8 +33,8 @@
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION 3
-#define MINOR_VERSION 25
-#define BUILD_NUMBER 30
+#define MINOR_VERSION 26
+#define BUILD_NUMBER 33
#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/deps/v8/src/version.h b/deps/v8/src/version.h
index 4b3e7e2bde..b0a6071521 100644
--- a/deps/v8/src/version.h
+++ b/deps/v8/src/version.h
@@ -1,29 +1,6 @@
// Copyright 2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_VERSION_H_
#define V8_VERSION_H_
diff --git a/deps/v8/src/vm-state-inl.h b/deps/v8/src/vm-state-inl.h
index 5bee438b65..f26c48bd7d 100644
--- a/deps/v8/src/vm-state-inl.h
+++ b/deps/v8/src/vm-state-inl.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_VM_STATE_INL_H_
#define V8_VM_STATE_INL_H_
diff --git a/deps/v8/src/vm-state.h b/deps/v8/src/vm-state.h
index f592bb92ca..9b3bed69d1 100644
--- a/deps/v8/src/vm-state.h
+++ b/deps/v8/src/vm-state.h
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_VM_STATE_H_
#define V8_VM_STATE_H_
diff --git a/deps/v8/src/weak_collection.js b/deps/v8/src/weak_collection.js
index 81d4ab536e..4c26d25743 100644
--- a/deps/v8/src/weak_collection.js
+++ b/deps/v8/src/weak_collection.js
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
"use strict";
diff --git a/deps/v8/src/win32-headers.h b/deps/v8/src/win32-headers.h
index ba595b97d4..5ede3b313d 100644
--- a/deps/v8/src/win32-headers.h
+++ b/deps/v8/src/win32-headers.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_WIN32_HEADERS_H_
#define V8_WIN32_HEADERS_H_
diff --git a/deps/v8/src/win32-math.cc b/deps/v8/src/win32-math.cc
index 8f6d077431..fb42383de9 100644
--- a/deps/v8/src/win32-math.cc
+++ b/deps/v8/src/win32-math.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Extra POSIX/ANSI routines for Win32 when using Visual Studio C++. Please
// refer to The Open Group Base Specification for specification of the correct
diff --git a/deps/v8/src/win32-math.h b/deps/v8/src/win32-math.h
index fd9312b0f5..7b7cbc9256 100644
--- a/deps/v8/src/win32-math.h
+++ b/deps/v8/src/win32-math.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// Extra POSIX/ANSI routines for Win32 when using Visual Studio C++. Please
// refer to The Open Group Base Specification for specification of the correct
diff --git a/deps/v8/src/x64/assembler-x64-inl.h b/deps/v8/src/x64/assembler-x64-inl.h
index a559b62758..be99022890 100644
--- a/deps/v8/src/x64/assembler-x64-inl.h
+++ b/deps/v8/src/x64/assembler-x64-inl.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_X64_ASSEMBLER_X64_INL_H_
#define V8_X64_ASSEMBLER_X64_INL_H_
@@ -43,7 +20,8 @@ namespace internal {
static const byte kCallOpcode = 0xE8;
-static const int kNoCodeAgeSequenceLength = 6;
+// The length of pushq(rbp), movp(rbp, rsp), Push(rsi) and Push(rdi).
+static const int kNoCodeAgeSequenceLength = kPointerSize == kInt64Size ? 6 : 17;
void Assembler::emitl(uint32_t x) {
@@ -392,12 +370,8 @@ bool RelocInfo::IsPatchedReturnSequence() {
// movq(rsp, rbp); pop(rbp); ret(n); int3 *6
// The 11th byte is int3 (0xCC) in the return sequence and
// REX.WB (0x48+register bit) for the call sequence.
-#ifdef ENABLE_DEBUGGER_SUPPORT
return pc_[Assembler::kMoveAddressIntoScratchRegisterInstructionLength] !=
0xCC;
-#else
- return false;
-#endif
}
@@ -483,14 +457,12 @@ void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
CPU::FlushICache(pc_, sizeof(Address));
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
visitor->VisitCodeAgeSequence(this);
-#ifdef ENABLE_DEBUGGER_SUPPORT
} else if (((RelocInfo::IsJSReturn(mode) &&
IsPatchedReturnSequence()) ||
(RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence())) &&
isolate->debug()->has_break_points()) {
visitor->VisitDebugTarget(this);
-#endif
} else if (RelocInfo::IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this);
}
@@ -512,14 +484,12 @@ void RelocInfo::Visit(Heap* heap) {
CPU::FlushICache(pc_, sizeof(Address));
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
StaticVisitor::VisitCodeAgeSequence(heap, this);
-#ifdef ENABLE_DEBUGGER_SUPPORT
} else if (heap->isolate()->debug()->has_break_points() &&
((RelocInfo::IsJSReturn(mode) &&
IsPatchedReturnSequence()) ||
(RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence()))) {
StaticVisitor::VisitDebugTarget(heap, this);
-#endif
} else if (RelocInfo::IsRuntimeEntry(mode)) {
StaticVisitor::VisitRuntimeEntry(this);
}
diff --git a/deps/v8/src/x64/assembler-x64.cc b/deps/v8/src/x64/assembler-x64.cc
index 60383da015..306a54d82b 100644
--- a/deps/v8/src/x64/assembler-x64.cc
+++ b/deps/v8/src/x64/assembler-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -52,13 +29,13 @@ ExternalReference ExternalReference::cpu_features() {
}
-void CpuFeatures::Probe() {
+void CpuFeatures::Probe(bool serializer_enabled) {
ASSERT(supported_ == CpuFeatures::kDefaultCpuFeatures);
#ifdef DEBUG
initialized_ = true;
#endif
supported_ = kDefaultCpuFeatures;
- if (Serializer::enabled()) {
+ if (serializer_enabled) {
supported_ |= OS::CpuFeaturesImpliedByPlatform();
return; // No features if we might serialize.
}
@@ -467,24 +444,30 @@ void Assembler::emit_operand(int code, const Operand& adr) {
// Assembler Instruction implementations.
-void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) {
+void Assembler::arithmetic_op(byte opcode,
+ Register reg,
+ const Operand& op,
+ int size) {
EnsureSpace ensure_space(this);
- emit_rex_64(reg, op);
+ emit_rex(reg, op, size);
emit(opcode);
emit_operand(reg, op);
}
-void Assembler::arithmetic_op(byte opcode, Register reg, Register rm_reg) {
+void Assembler::arithmetic_op(byte opcode,
+ Register reg,
+ Register rm_reg,
+ int size) {
EnsureSpace ensure_space(this);
ASSERT((opcode & 0xC6) == 2);
if (rm_reg.low_bits() == 4) { // Forces SIB byte.
// Swap reg and rm_reg and change opcode operand order.
- emit_rex_64(rm_reg, reg);
+ emit_rex(rm_reg, reg, size);
emit(opcode ^ 0x02);
emit_modrm(rm_reg, reg);
} else {
- emit_rex_64(reg, rm_reg);
+ emit_rex(reg, rm_reg, size);
emit(opcode);
emit_modrm(reg, rm_reg);
}
@@ -520,37 +503,45 @@ void Assembler::arithmetic_op_16(byte opcode,
}
-void Assembler::arithmetic_op_32(byte opcode, Register reg, Register rm_reg) {
+void Assembler::arithmetic_op_8(byte opcode, Register reg, const Operand& op) {
+ EnsureSpace ensure_space(this);
+ if (!reg.is_byte_register()) {
+ // Register is not one of al, bl, cl, dl. Its encoding needs REX.
+ emit_rex_32(reg);
+ }
+ emit(opcode);
+ emit_operand(reg, op);
+}
+
+
+void Assembler::arithmetic_op_8(byte opcode, Register reg, Register rm_reg) {
EnsureSpace ensure_space(this);
ASSERT((opcode & 0xC6) == 2);
- if (rm_reg.low_bits() == 4) { // Forces SIB byte.
+ if (rm_reg.low_bits() == 4) { // Forces SIB byte.
// Swap reg and rm_reg and change opcode operand order.
- emit_optional_rex_32(rm_reg, reg);
- emit(opcode ^ 0x02); // E.g. 0x03 -> 0x01 for ADD.
+ if (!rm_reg.is_byte_register() || !reg.is_byte_register()) {
+ // Register is not one of al, bl, cl, dl. Its encoding needs REX.
+ emit_rex_32(rm_reg, reg);
+ }
+ emit(opcode ^ 0x02);
emit_modrm(rm_reg, reg);
} else {
- emit_optional_rex_32(reg, rm_reg);
+ if (!reg.is_byte_register() || !rm_reg.is_byte_register()) {
+ // Register is not one of al, bl, cl, dl. Its encoding needs REX.
+ emit_rex_32(reg, rm_reg);
+ }
emit(opcode);
emit_modrm(reg, rm_reg);
}
}
-void Assembler::arithmetic_op_32(byte opcode,
- Register reg,
- const Operand& rm_reg) {
- EnsureSpace ensure_space(this);
- emit_optional_rex_32(reg, rm_reg);
- emit(opcode);
- emit_operand(reg, rm_reg);
-}
-
-
void Assembler::immediate_arithmetic_op(byte subcode,
Register dst,
- Immediate src) {
+ Immediate src,
+ int size) {
EnsureSpace ensure_space(this);
- emit_rex_64(dst);
+ emit_rex(dst, size);
if (is_int8(src.value_)) {
emit(0x83);
emit_modrm(subcode, dst);
@@ -567,9 +558,10 @@ void Assembler::immediate_arithmetic_op(byte subcode,
void Assembler::immediate_arithmetic_op(byte subcode,
const Operand& dst,
- Immediate src) {
+ Immediate src,
+ int size) {
EnsureSpace ensure_space(this);
- emit_rex_64(dst);
+ emit_rex(dst, size);
if (is_int8(src.value_)) {
emit(0x83);
emit_operand(subcode, dst);
@@ -621,43 +613,6 @@ void Assembler::immediate_arithmetic_op_16(byte subcode,
}
-void Assembler::immediate_arithmetic_op_32(byte subcode,
- Register dst,
- Immediate src) {
- EnsureSpace ensure_space(this);
- emit_optional_rex_32(dst);
- if (is_int8(src.value_)) {
- emit(0x83);
- emit_modrm(subcode, dst);
- emit(src.value_);
- } else if (dst.is(rax)) {
- emit(0x05 | (subcode << 3));
- emitl(src.value_);
- } else {
- emit(0x81);
- emit_modrm(subcode, dst);
- emitl(src.value_);
- }
-}
-
-
-void Assembler::immediate_arithmetic_op_32(byte subcode,
- const Operand& dst,
- Immediate src) {
- EnsureSpace ensure_space(this);
- emit_optional_rex_32(dst);
- if (is_int8(src.value_)) {
- emit(0x83);
- emit_operand(subcode, dst);
- emit(src.value_);
- } else {
- emit(0x81);
- emit_operand(subcode, dst);
- emitl(src.value_);
- }
-}
-
-
void Assembler::immediate_arithmetic_op_8(byte subcode,
const Operand& dst,
Immediate src) {
@@ -675,8 +630,8 @@ void Assembler::immediate_arithmetic_op_8(byte subcode,
Immediate src) {
EnsureSpace ensure_space(this);
if (!dst.is_byte_register()) {
- // Use 64-bit mode byte registers.
- emit_rex_64(dst);
+ // Register is not one of al, bl, cl, dl. Its encoding needs REX.
+ emit_rex_32(dst);
}
ASSERT(is_int8(src.value_) || is_uint8(src.value_));
emit(0x80);
@@ -685,15 +640,19 @@ void Assembler::immediate_arithmetic_op_8(byte subcode,
}
-void Assembler::shift(Register dst, Immediate shift_amount, int subcode) {
+void Assembler::shift(Register dst,
+ Immediate shift_amount,
+ int subcode,
+ int size) {
EnsureSpace ensure_space(this);
- ASSERT(is_uint6(shift_amount.value_)); // illegal shift count
+ ASSERT(size == kInt64Size ? is_uint6(shift_amount.value_)
+ : is_uint5(shift_amount.value_));
if (shift_amount.value_ == 1) {
- emit_rex_64(dst);
+ emit_rex(dst, size);
emit(0xD1);
emit_modrm(subcode, dst);
} else {
- emit_rex_64(dst);
+ emit_rex(dst, size);
emit(0xC1);
emit_modrm(subcode, dst);
emit(shift_amount.value_);
@@ -701,38 +660,14 @@ void Assembler::shift(Register dst, Immediate shift_amount, int subcode) {
}
-void Assembler::shift(Register dst, int subcode) {
- EnsureSpace ensure_space(this);
- emit_rex_64(dst);
- emit(0xD3);
- emit_modrm(subcode, dst);
-}
-
-
-void Assembler::shift_32(Register dst, int subcode) {
+void Assembler::shift(Register dst, int subcode, int size) {
EnsureSpace ensure_space(this);
- emit_optional_rex_32(dst);
+ emit_rex(dst, size);
emit(0xD3);
emit_modrm(subcode, dst);
}
-void Assembler::shift_32(Register dst, Immediate shift_amount, int subcode) {
- EnsureSpace ensure_space(this);
- ASSERT(is_uint5(shift_amount.value_)); // illegal shift count
- if (shift_amount.value_ == 1) {
- emit_optional_rex_32(dst);
- emit(0xD1);
- emit_modrm(subcode, dst);
- } else {
- emit_optional_rex_32(dst);
- emit(0xC1);
- emit_modrm(subcode, dst);
- emit(shift_amount.value_);
- }
-}
-
-
void Assembler::bt(const Operand& dst, Register src) {
EnsureSpace ensure_space(this);
emit_rex_64(src, dst);
@@ -1431,6 +1366,15 @@ void Assembler::movl(const Operand& dst, Label* src) {
}
+void Assembler::movsxbl(Register dst, const Operand& src) {
+ EnsureSpace ensure_space(this);
+ emit_optional_rex_32(dst, src);
+ emit(0x0F);
+ emit(0xBE);
+ emit_operand(dst, src);
+}
+
+
void Assembler::movsxbq(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
emit_rex_64(dst, src);
@@ -1440,6 +1384,15 @@ void Assembler::movsxbq(Register dst, const Operand& src) {
}
+void Assembler::movsxwl(Register dst, const Operand& src) {
+ EnsureSpace ensure_space(this);
+ emit_optional_rex_32(dst, src);
+ emit(0x0F);
+ emit(0xBF);
+ emit_operand(dst, src);
+}
+
+
void Assembler::movsxwq(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
emit_rex_64(dst, src);
@@ -2977,12 +2930,7 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
ASSERT(!RelocInfo::IsNone(rmode));
if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
// Don't record external references unless the heap will be serialized.
-#ifdef DEBUG
- if (!Serializer::enabled()) {
- Serializer::TooLateToEnableNow();
- }
-#endif
- if (!Serializer::enabled() && !emit_debug_code()) {
+ if (!Serializer::enabled(isolate()) && !emit_debug_code()) {
return;
}
} else if (rmode == RelocInfo::CODE_AGE_SEQUENCE) {
@@ -3016,16 +2964,17 @@ void Assembler::RecordComment(const char* msg, bool force) {
}
-MaybeObject* Assembler::AllocateConstantPool(Heap* heap) {
+Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
// No out-of-line constant pool support.
- UNREACHABLE();
- return NULL;
+ ASSERT(!FLAG_enable_ool_constant_pool);
+ return isolate->factory()->empty_constant_pool_array();
}
void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
// No out-of-line constant pool support.
- UNREACHABLE();
+ ASSERT(!FLAG_enable_ool_constant_pool);
+ return;
}
diff --git a/deps/v8/src/x64/assembler-x64.h b/deps/v8/src/x64/assembler-x64.h
index d47ca32e0d..685d46c094 100644
--- a/deps/v8/src/x64/assembler-x64.h
+++ b/deps/v8/src/x64/assembler-x64.h
@@ -357,6 +357,10 @@ inline Condition ReverseCondition(Condition cc) {
class Immediate BASE_EMBEDDED {
public:
explicit Immediate(int32_t value) : value_(value) {}
+ explicit Immediate(Smi* value) {
+ ASSERT(SmiValuesAre31Bits()); // Only available for 31-bit SMI.
+ value_ = static_cast<int32_t>(reinterpret_cast<intptr_t>(value));
+ }
private:
int32_t value_;
@@ -446,7 +450,7 @@ class CpuFeatures : public AllStatic {
public:
// Detect features of the target CPU. Set safe defaults if the serializer
// is enabled (snapshots must be portable).
- static void Probe();
+ static void Probe(bool serializer_enabled);
// Check whether a feature is supported by the target CPU.
static bool IsSupported(CpuFeature f) {
@@ -459,15 +463,11 @@ class CpuFeatures : public AllStatic {
return Check(f, supported_);
}
- static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
- ASSERT(initialized_);
- return Check(f, found_by_runtime_probing_only_);
- }
-
- static bool IsSafeForSnapshot(CpuFeature f) {
+ static bool IsSafeForSnapshot(Isolate* isolate, CpuFeature f) {
return Check(f, cross_compile_) ||
(IsSupported(f) &&
- (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
+ !(Serializer::enabled(isolate) &&
+ Check(f, found_by_runtime_probing_only_)));
}
static bool VerifyCrossCompiling() {
@@ -480,6 +480,8 @@ class CpuFeatures : public AllStatic {
(cross_compile_ & mask) == mask;
}
+ static bool SupportsCrankshaft() { return true; }
+
private:
static bool Check(CpuFeature f, uint64_t set) {
return (set & flag2set(f)) != 0;
@@ -532,6 +534,18 @@ class CpuFeatures : public AllStatic {
V(xor)
+// Shift instructions on operands/registers with kPointerSize, kInt32Size and
+// kInt64Size.
+#define SHIFT_INSTRUCTION_LIST(V) \
+ V(rol, 0x0) \
+ V(ror, 0x1) \
+ V(rcl, 0x2) \
+ V(rcr, 0x3) \
+ V(shl, 0x4) \
+ V(shr, 0x5) \
+ V(sar, 0x7) \
+
+
class Assembler : public AssemblerBase {
private:
// We check before assembling an instruction that there is sufficient
@@ -680,6 +694,8 @@ class Assembler : public AssemblerBase {
// - Instructions on 64-bit (quadword) operands/registers use 'q'.
// - Instructions on operands/registers with pointer size use 'p'.
+ STATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size);
+
#define DECLARE_INSTRUCTION(instruction) \
template<class P1> \
void instruction##p(P1 p1) { \
@@ -776,7 +792,9 @@ class Assembler : public AssemblerBase {
void movq(Register dst, int64_t value);
void movq(Register dst, uint64_t value);
+ void movsxbl(Register dst, const Operand& src);
void movsxbq(Register dst, const Operand& src);
+ void movsxwl(Register dst, const Operand& src);
void movsxwq(Register dst, const Operand& src);
void movsxlq(Register dst, Register src);
void movsxlq(Register dst, const Operand& src);
@@ -806,15 +824,15 @@ class Assembler : public AssemblerBase {
void cmpb_al(Immediate src);
void cmpb(Register dst, Register src) {
- arithmetic_op(0x3A, dst, src);
+ arithmetic_op_8(0x3A, dst, src);
}
void cmpb(Register dst, const Operand& src) {
- arithmetic_op(0x3A, dst, src);
+ arithmetic_op_8(0x3A, dst, src);
}
void cmpb(const Operand& dst, Register src) {
- arithmetic_op(0x38, src, dst);
+ arithmetic_op_8(0x38, src, dst);
}
void cmpb(const Operand& dst, Immediate src) {
@@ -856,33 +874,32 @@ class Assembler : public AssemblerBase {
// Multiply rax by src, put the result in rdx:rax.
void mul(Register src);
- void rcl(Register dst, Immediate imm8) {
- shift(dst, imm8, 0x2);
- }
-
- void rol(Register dst, Immediate imm8) {
- shift(dst, imm8, 0x0);
- }
-
- void roll(Register dst, Immediate imm8) {
- shift_32(dst, imm8, 0x0);
- }
-
- void rcr(Register dst, Immediate imm8) {
- shift(dst, imm8, 0x3);
- }
-
- void ror(Register dst, Immediate imm8) {
- shift(dst, imm8, 0x1);
- }
-
- void rorl(Register dst, Immediate imm8) {
- shift_32(dst, imm8, 0x1);
- }
-
- void rorl_cl(Register dst) {
- shift_32(dst, 0x1);
- }
+#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode) \
+ void instruction##p(Register dst, Immediate imm8) { \
+ shift(dst, imm8, subcode, kPointerSize); \
+ } \
+ \
+ void instruction##l(Register dst, Immediate imm8) { \
+ shift(dst, imm8, subcode, kInt32Size); \
+ } \
+ \
+ void instruction##q(Register dst, Immediate imm8) { \
+ shift(dst, imm8, subcode, kInt64Size); \
+ } \
+ \
+ void instruction##p_cl(Register dst) { \
+ shift(dst, subcode, kPointerSize); \
+ } \
+ \
+ void instruction##l_cl(Register dst) { \
+ shift(dst, subcode, kInt32Size); \
+ } \
+ \
+ void instruction##q_cl(Register dst) { \
+ shift(dst, subcode, kInt64Size); \
+ }
+ SHIFT_INSTRUCTION_LIST(DECLARE_SHIFT_INSTRUCTION)
+#undef DECLARE_SHIFT_INSTRUCTION
// Shifts dst:src left by cl bits, affecting only dst.
void shld(Register dst, Register src);
@@ -890,60 +907,6 @@ class Assembler : public AssemblerBase {
// Shifts src:dst right by cl bits, affecting only dst.
void shrd(Register dst, Register src);
- // Shifts dst right, duplicating sign bit, by shift_amount bits.
- // Shifting by 1 is handled efficiently.
- void sar(Register dst, Immediate shift_amount) {
- shift(dst, shift_amount, 0x7);
- }
-
- // Shifts dst right, duplicating sign bit, by shift_amount bits.
- // Shifting by 1 is handled efficiently.
- void sarl(Register dst, Immediate shift_amount) {
- shift_32(dst, shift_amount, 0x7);
- }
-
- // Shifts dst right, duplicating sign bit, by cl % 64 bits.
- void sar_cl(Register dst) {
- shift(dst, 0x7);
- }
-
- // Shifts dst right, duplicating sign bit, by cl % 64 bits.
- void sarl_cl(Register dst) {
- shift_32(dst, 0x7);
- }
-
- void shl(Register dst, Immediate shift_amount) {
- shift(dst, shift_amount, 0x4);
- }
-
- void shl_cl(Register dst) {
- shift(dst, 0x4);
- }
-
- void shll_cl(Register dst) {
- shift_32(dst, 0x4);
- }
-
- void shll(Register dst, Immediate shift_amount) {
- shift_32(dst, shift_amount, 0x4);
- }
-
- void shr(Register dst, Immediate shift_amount) {
- shift(dst, shift_amount, 0x5);
- }
-
- void shr_cl(Register dst) {
- shift(dst, 0x5);
- }
-
- void shrl_cl(Register dst) {
- shift_32(dst, 0x5);
- }
-
- void shrl(Register dst, Immediate shift_amount) {
- shift_32(dst, shift_amount, 0x5);
- }
-
void store_rax(void* dst, RelocInfo::Mode mode);
void store_rax(ExternalReference ref);
@@ -1214,7 +1177,7 @@ class Assembler : public AssemblerBase {
void RecordComment(const char* msg, bool force = false);
// Allocate a constant pool of the correct size for the generated code.
- MaybeObject* AllocateConstantPool(Heap* heap);
+ Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate);
// Generate the constant pool for the generated code.
void PopulateConstantPool(ConstantPoolArray* constant_pool);
@@ -1425,14 +1388,16 @@ class Assembler : public AssemblerBase {
// AND, OR, XOR, or CMP. The encodings of these operations are all
// similar, differing just in the opcode or in the reg field of the
// ModR/M byte.
+ void arithmetic_op_8(byte opcode, Register reg, Register rm_reg);
+ void arithmetic_op_8(byte opcode, Register reg, const Operand& rm_reg);
void arithmetic_op_16(byte opcode, Register reg, Register rm_reg);
void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg);
- void arithmetic_op_32(byte opcode, Register reg, Register rm_reg);
- void arithmetic_op_32(byte opcode, Register reg, const Operand& rm_reg);
- void arithmetic_op(byte opcode, Register reg, Register rm_reg);
- void arithmetic_op(byte opcode, Register reg, const Operand& rm_reg);
- void immediate_arithmetic_op(byte subcode, Register dst, Immediate src);
- void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src);
+ // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
+ void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size);
+ void arithmetic_op(byte opcode,
+ Register reg,
+ const Operand& rm_reg,
+ int size);
// Operate on a byte in memory or register.
void immediate_arithmetic_op_8(byte subcode,
Register dst,
@@ -1447,20 +1412,20 @@ class Assembler : public AssemblerBase {
void immediate_arithmetic_op_16(byte subcode,
const Operand& dst,
Immediate src);
- // Operate on a 32-bit word in memory or register.
- void immediate_arithmetic_op_32(byte subcode,
- Register dst,
- Immediate src);
- void immediate_arithmetic_op_32(byte subcode,
- const Operand& dst,
- Immediate src);
+ // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
+ void immediate_arithmetic_op(byte subcode,
+ Register dst,
+ Immediate src,
+ int size);
+ void immediate_arithmetic_op(byte subcode,
+ const Operand& dst,
+ Immediate src,
+ int size);
// Emit machine code for a shift operation.
- void shift(Register dst, Immediate shift_amount, int subcode);
- void shift_32(Register dst, Immediate shift_amount, int subcode);
+ void shift(Register dst, Immediate shift_amount, int subcode, int size);
// Shift dst by cl % 64 bits.
- void shift(Register dst, int subcode);
- void shift_32(Register dst, int subcode);
+ void shift(Register dst, int subcode, int size);
void emit_farith(int b1, int b2, int i);
@@ -1473,138 +1438,63 @@ class Assembler : public AssemblerBase {
// Arithmetics
void emit_add(Register dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x03, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x03, dst, src);
- }
+ arithmetic_op(0x03, dst, src, size);
}
void emit_add(Register dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x0, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x0, dst, src);
- }
+ immediate_arithmetic_op(0x0, dst, src, size);
}
void emit_add(Register dst, const Operand& src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x03, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x03, dst, src);
- }
+ arithmetic_op(0x03, dst, src, size);
}
void emit_add(const Operand& dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x1, src, dst);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x1, src, dst);
- }
+ arithmetic_op(0x1, src, dst, size);
}
void emit_add(const Operand& dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x0, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x0, dst, src);
- }
+ immediate_arithmetic_op(0x0, dst, src, size);
}
void emit_and(Register dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x23, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x23, dst, src);
- }
+ arithmetic_op(0x23, dst, src, size);
}
void emit_and(Register dst, const Operand& src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x23, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x23, dst, src);
- }
+ arithmetic_op(0x23, dst, src, size);
}
void emit_and(const Operand& dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x21, src, dst);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x21, src, dst);
- }
+ arithmetic_op(0x21, src, dst, size);
}
void emit_and(Register dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x4, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x4, dst, src);
- }
+ immediate_arithmetic_op(0x4, dst, src, size);
}
void emit_and(const Operand& dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x4, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x4, dst, src);
- }
+ immediate_arithmetic_op(0x4, dst, src, size);
}
void emit_cmp(Register dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x3B, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x3B, dst, src);
- }
+ arithmetic_op(0x3B, dst, src, size);
}
void emit_cmp(Register dst, const Operand& src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x3B, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x3B, dst, src);
- }
+ arithmetic_op(0x3B, dst, src, size);
}
void emit_cmp(const Operand& dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x39, src, dst);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x39, src, dst);
- }
+ arithmetic_op(0x39, src, dst, size);
}
void emit_cmp(Register dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x7, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x7, dst, src);
- }
+ immediate_arithmetic_op(0x7, dst, src, size);
}
void emit_cmp(const Operand& dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x7, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x7, dst, src);
- }
+ immediate_arithmetic_op(0x7, dst, src, size);
}
void emit_dec(Register dst, int size);
@@ -1644,99 +1534,49 @@ class Assembler : public AssemblerBase {
void emit_not(const Operand& dst, int size);
void emit_or(Register dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x0B, dst, src);
- } else {
- arithmetic_op_32(0x0B, dst, src);
- }
+ arithmetic_op(0x0B, dst, src, size);
}
void emit_or(Register dst, const Operand& src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x0B, dst, src);
- } else {
- arithmetic_op_32(0x0B, dst, src);
- }
+ arithmetic_op(0x0B, dst, src, size);
}
void emit_or(const Operand& dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x9, src, dst);
- } else {
- arithmetic_op_32(0x9, src, dst);
- }
+ arithmetic_op(0x9, src, dst, size);
}
void emit_or(Register dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x1, dst, src);
- } else {
- immediate_arithmetic_op_32(0x1, dst, src);
- }
+ immediate_arithmetic_op(0x1, dst, src, size);
}
void emit_or(const Operand& dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x1, dst, src);
- } else {
- immediate_arithmetic_op_32(0x1, dst, src);
- }
+ immediate_arithmetic_op(0x1, dst, src, size);
}
void emit_repmovs(int size);
void emit_sbb(Register dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x1b, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x1b, dst, src);
- }
+ arithmetic_op(0x1b, dst, src, size);
}
void emit_sub(Register dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x2B, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x2B, dst, src);
- }
+ arithmetic_op(0x2B, dst, src, size);
}
void emit_sub(Register dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x5, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x5, dst, src);
- }
+ immediate_arithmetic_op(0x5, dst, src, size);
}
void emit_sub(Register dst, const Operand& src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x2B, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x2B, dst, src);
- }
+ arithmetic_op(0x2B, dst, src, size);
}
void emit_sub(const Operand& dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x29, src, dst);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x29, src, dst);
- }
+ arithmetic_op(0x29, src, dst, size);
}
void emit_sub(const Operand& dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x5, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x5, dst, src);
- }
+ immediate_arithmetic_op(0x5, dst, src, size);
}
void emit_test(Register dst, Register src, int size);
@@ -1748,52 +1588,29 @@ class Assembler : public AssemblerBase {
void emit_xchg(Register dst, Register src, int size);
void emit_xor(Register dst, Register src, int size) {
- if (size == kInt64Size) {
- if (dst.code() == src.code()) {
- arithmetic_op_32(0x33, dst, src);
- } else {
- arithmetic_op(0x33, dst, src);
- }
+ if (size == kInt64Size && dst.code() == src.code()) {
+ // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
+ // there is no need to make this a 64 bit operation.
+ arithmetic_op(0x33, dst, src, kInt32Size);
} else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x33, dst, src);
+ arithmetic_op(0x33, dst, src, size);
}
}
void emit_xor(Register dst, const Operand& src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x33, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x33, dst, src);
- }
+ arithmetic_op(0x33, dst, src, size);
}
void emit_xor(Register dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x6, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x6, dst, src);
- }
+ immediate_arithmetic_op(0x6, dst, src, size);
}
void emit_xor(const Operand& dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x6, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x6, dst, src);
- }
+ immediate_arithmetic_op(0x6, dst, src, size);
}
void emit_xor(const Operand& dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x31, src, dst);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x31, src, dst);
- }
+ arithmetic_op(0x31, src, dst, size);
}
friend class CodePatcher;
diff --git a/deps/v8/src/x64/builtins-x64.cc b/deps/v8/src/x64/builtins-x64.cc
index d5b1a73868..9e3b89ac61 100644
--- a/deps/v8/src/x64/builtins-x64.cc
+++ b/deps/v8/src/x64/builtins-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -163,13 +140,11 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
if (FLAG_inline_new) {
Label undo_allocation;
-#ifdef ENABLE_DEBUGGER_SUPPORT
ExternalReference debug_step_in_fp =
ExternalReference::debug_step_in_fp_address(masm->isolate());
__ Move(kScratchRegister, debug_step_in_fp);
__ cmpp(Operand(kScratchRegister, 0), Immediate(0));
__ j(not_equal, &rt_call);
-#endif
// Verified that the constructor is a JSFunction.
// Load the initial map and verify that it is in fact a map.
@@ -214,7 +189,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
// Now allocate the JSObject on the heap.
__ movzxbp(rdi, FieldOperand(rax, Map::kInstanceSizeOffset));
- __ shl(rdi, Immediate(kPointerSizeLog2));
+ __ shlp(rdi, Immediate(kPointerSizeLog2));
if (create_memento) {
__ addp(rdi, Immediate(AllocationMemento::kSize));
}
@@ -600,7 +575,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
// No type feedback cell is available
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
// Expects rdi to hold function pointer.
- CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
+ CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
__ CallStub(&stub);
} else {
ParameterCount actual(rax);
@@ -749,7 +724,7 @@ static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
// Tear down internal frame.
}
- __ Pop(MemOperand(rsp, 0)); // Ignore state offset
+ __ DropUnderReturnAddress(1); // Ignore state offset
__ ret(0); // Return to IC Miss stub, continuation still on stack.
}
@@ -926,12 +901,13 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
__ bind(&shift_arguments);
{ Label loop;
__ movp(rcx, rax);
+ StackArgumentsAccessor args(rsp, rcx);
__ bind(&loop);
- __ movp(rbx, Operand(rsp, rcx, times_pointer_size, 0));
- __ movp(Operand(rsp, rcx, times_pointer_size, 1 * kPointerSize), rbx);
+ __ movp(rbx, args.GetArgumentOperand(1));
+ __ movp(args.GetArgumentOperand(0), rbx);
__ decp(rcx);
- __ j(not_sign, &loop); // While non-negative (to copy return address).
- __ popq(rbx); // Discard copy of return address.
+ __ j(not_zero, &loop); // While non-zero.
+ __ DropUnderReturnAddress(1, rbx); // Drop one slot under return address.
__ decp(rax); // One fewer argument (first argument is new receiver).
}
@@ -963,9 +939,8 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
// expected arguments matches what we're providing. If so, jump
// (tail-call) to the code in register edx without checking arguments.
__ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
- __ movsxlq(rbx,
- FieldOperand(rdx,
- SharedFunctionInfo::kFormalParameterCountOffset));
+ __ LoadSharedFunctionInfoSpecialField(rbx, rdx,
+ SharedFunctionInfo::kFormalParameterCountOffset);
__ movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
__ cmpp(rax, rbx);
__ j(not_equal,
@@ -1018,7 +993,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// Out of stack space.
__ Push(Operand(rbp, kFunctionOffset));
__ Push(rax);
- __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
+ __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
__ bind(&okay);
// End of stack check.
@@ -1323,6 +1298,32 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
}
+static void ArgumentsAdaptorStackCheck(MacroAssembler* masm,
+ Label* stack_overflow) {
+ // ----------- S t a t e -------------
+ // -- rax : actual number of arguments
+ // -- rbx : expected number of arguments
+ // -- rdi: function (passed through to callee)
+ // -----------------------------------
+ // Check the stack for overflow. We are not trying to catch
+ // interruptions (e.g. debug break and preemption) here, so the "real stack
+ // limit" is checked.
+ Label okay;
+ __ LoadRoot(rdx, Heap::kRealStackLimitRootIndex);
+ __ movp(rcx, rsp);
+ // Make rcx the space we have left. The stack might already be overflowed
+ // here which will cause rcx to become negative.
+ __ subp(rcx, rdx);
+ // Make rdx the space we need for the array when it is unrolled onto the
+ // stack.
+ __ movp(rdx, rbx);
+ __ shlp(rdx, Immediate(kPointerSizeLog2));
+ // Check if the arguments will overflow the stack.
+ __ cmpp(rcx, rdx);
+ __ j(less_equal, stack_overflow); // Signed comparison.
+}
+
+
static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
__ pushq(rbp);
__ movp(rbp, rsp);
@@ -1368,6 +1369,9 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->arguments_adaptors(), 1);
+ Label stack_overflow;
+ ArgumentsAdaptorStackCheck(masm, &stack_overflow);
+
Label enough, too_few;
__ movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
__ cmpp(rax, rbx);
@@ -1440,6 +1444,14 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// -------------------------------------------
__ bind(&dont_adapt_arguments);
__ jmp(rdx);
+
+ __ bind(&stack_overflow);
+ {
+ FrameScope frame(masm, StackFrame::MANUAL);
+ EnterArgumentsAdaptorFrame(masm);
+ __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
+ __ int3();
+ }
}
diff --git a/deps/v8/src/x64/code-stubs-x64.cc b/deps/v8/src/x64/code-stubs-x64.cc
index c949a423a2..546595ad41 100644
--- a/deps/v8/src/x64/code-stubs-x64.cc
+++ b/deps/v8/src/x64/code-stubs-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -40,7 +17,6 @@ namespace internal {
void FastNewClosureStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rbx };
descriptor->register_param_count_ = 1;
@@ -51,7 +27,6 @@ void FastNewClosureStub::InitializeInterfaceDescriptor(
void FastNewContextStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdi };
descriptor->register_param_count_ = 1;
@@ -61,7 +36,6 @@ void FastNewContextStub::InitializeInterfaceDescriptor(
void ToNumberStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax };
descriptor->register_param_count_ = 1;
@@ -71,7 +45,6 @@ void ToNumberStub::InitializeInterfaceDescriptor(
void NumberToStringStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax };
descriptor->register_param_count_ = 1;
@@ -82,7 +55,6 @@ void NumberToStringStub::InitializeInterfaceDescriptor(
void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax, rbx, rcx };
descriptor->register_param_count_ = 3;
@@ -94,7 +66,6 @@ void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax, rbx, rcx, rdx };
descriptor->register_param_count_ = 4;
@@ -105,7 +76,6 @@ void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rbx, rdx };
descriptor->register_param_count_ = 2;
@@ -115,7 +85,6 @@ void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rax };
descriptor->register_param_count_ = 2;
@@ -126,7 +95,6 @@ void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rax };
descriptor->register_param_count_ = 2;
@@ -137,7 +105,6 @@ void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
void RegExpConstructResultStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rcx, rbx, rax };
descriptor->register_param_count_ = 3;
@@ -148,7 +115,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor(
void LoadFieldStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax };
descriptor->register_param_count_ = 1;
@@ -158,7 +124,6 @@ void LoadFieldStub::InitializeInterfaceDescriptor(
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx };
descriptor->register_param_count_ = 1;
@@ -168,7 +133,6 @@ void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
void StringLengthStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax, rcx };
descriptor->register_param_count_ = 2;
@@ -178,7 +142,6 @@ void StringLengthStub::InitializeInterfaceDescriptor(
void KeyedStringLengthStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rax };
descriptor->register_param_count_ = 2;
@@ -188,7 +151,6 @@ void KeyedStringLengthStub::InitializeInterfaceDescriptor(
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rcx, rax };
descriptor->register_param_count_ = 3;
@@ -199,7 +161,6 @@ void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
void TransitionElementsKindStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax, rbx };
descriptor->register_param_count_ = 2;
@@ -210,7 +171,6 @@ void TransitionElementsKindStub::InitializeInterfaceDescriptor(
static void InitializeArrayConstructorDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor,
int constant_stack_parameter_count) {
// register state
@@ -239,7 +199,6 @@ static void InitializeArrayConstructorDescriptor(
static void InitializeInternalArrayConstructorDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor,
int constant_stack_parameter_count) {
// register state
@@ -267,49 +226,42 @@ static void InitializeInternalArrayConstructorDescriptor(
void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(isolate, descriptor, 0);
+ InitializeArrayConstructorDescriptor(descriptor, 0);
}
void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(isolate, descriptor, 1);
+ InitializeArrayConstructorDescriptor(descriptor, 1);
}
void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(isolate, descriptor, -1);
+ InitializeArrayConstructorDescriptor(descriptor, -1);
}
void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 0);
+ InitializeInternalArrayConstructorDescriptor(descriptor, 0);
}
void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 1);
+ InitializeInternalArrayConstructorDescriptor(descriptor, 1);
}
void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(isolate, descriptor, -1);
+ InitializeInternalArrayConstructorDescriptor(descriptor, -1);
}
void CompareNilICStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax };
descriptor->register_param_count_ = 1;
@@ -317,12 +269,11 @@ void CompareNilICStub::InitializeInterfaceDescriptor(
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(CompareNilIC_Miss);
descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate));
+ ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate()));
}
void ToBooleanStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax };
descriptor->register_param_count_ = 1;
@@ -330,12 +281,11 @@ void ToBooleanStub::InitializeInterfaceDescriptor(
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(ToBooleanIC_Miss);
descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate));
+ ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate()));
}
void StoreGlobalStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rcx, rax };
descriptor->register_param_count_ = 3;
@@ -346,7 +296,6 @@ void StoreGlobalStub::InitializeInterfaceDescriptor(
void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rax, rbx, rcx, rdx };
descriptor->register_param_count_ = 4;
@@ -357,19 +306,17 @@ void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
void BinaryOpICStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rax };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate));
+ ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate()));
}
void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rcx, rdx, rax };
descriptor->register_param_count_ = 3;
@@ -380,7 +327,6 @@ void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
void StringAddStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { rdx, rax };
descriptor->register_param_count_ = 2;
@@ -479,10 +425,9 @@ void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
// Update the static counter each time a new code stub is generated.
- Isolate* isolate = masm->isolate();
- isolate->counters()->code_stubs()->Increment();
+ isolate()->counters()->code_stubs()->Increment();
- CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate);
+ CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor();
int param_count = descriptor->register_param_count_;
{
// Call the runtime system in a fresh internal frame.
@@ -506,11 +451,11 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
const int argument_count = 1;
__ PrepareCallCFunction(argument_count);
__ LoadAddress(arg_reg_1,
- ExternalReference::isolate_address(masm->isolate()));
+ ExternalReference::isolate_address(isolate()));
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(
- ExternalReference::store_buffer_overflow_function(masm->isolate()),
+ ExternalReference::store_buffer_overflow_function(isolate()),
argument_count);
__ PopCallerSaved(save_doubles_);
__ ret(0);
@@ -871,11 +816,11 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ Cvtlsi2sd(double_exponent, exponent);
// Returning or bailing out.
- Counters* counters = masm->isolate()->counters();
+ Counters* counters = isolate()->counters();
if (exponent_type_ == ON_STACK) {
// The arguments are still on the stack.
__ bind(&call_runtime);
- __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
+ __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1);
// The stub is called from non-optimized code, which expects the result
// as heap number in rax.
@@ -893,7 +838,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
AllowExternalCallThatCantCauseGC scope(masm);
__ PrepareCallCFunction(2);
__ CallCFunction(
- ExternalReference::power_double_double_function(masm->isolate()), 2);
+ ExternalReference::power_double_double_function(isolate()), 2);
}
// Return value is in xmm0.
__ movsd(double_result, xmm0);
@@ -914,7 +859,7 @@ void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
// -- rdx : receiver
// -- rsp[0] : return address
// -----------------------------------
- __ Cmp(rax, masm->isolate()->factory()->prototype_string());
+ __ Cmp(rax, isolate()->factory()->prototype_string());
__ j(not_equal, &miss);
receiver = rdx;
} else {
@@ -1000,7 +945,7 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
// rbx: the mapped parameter count (untagged)
// rax: the allocated object (tagged).
- Factory* factory = masm->isolate()->factory();
+ Factory* factory = isolate()->factory();
StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
__ SmiToInteger64(rbx, args.GetArgumentOperand(2));
@@ -1363,11 +1308,10 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
ARGUMENTS_DONT_CONTAIN_RECEIVER);
Label runtime;
// Ensure that a RegExp stack is allocated.
- Isolate* isolate = masm->isolate();
ExternalReference address_of_regexp_stack_memory_address =
- ExternalReference::address_of_regexp_stack_memory_address(isolate);
+ ExternalReference::address_of_regexp_stack_memory_address(isolate());
ExternalReference address_of_regexp_stack_memory_size =
- ExternalReference::address_of_regexp_stack_memory_size(isolate);
+ ExternalReference::address_of_regexp_stack_memory_size(isolate());
__ Load(kScratchRegister, address_of_regexp_stack_memory_size);
__ testp(kScratchRegister, kScratchRegister);
__ j(zero, &runtime);
@@ -1519,7 +1463,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// rcx: encoding of subject string (1 if ASCII 0 if two_byte);
// r11: code
// All checks done. Now push arguments for native regexp code.
- Counters* counters = masm->isolate()->counters();
+ Counters* counters = isolate()->counters();
__ IncrementCounter(counters->regexp_entry_native(), 1);
// Isolates: note we add an additional parameter here (isolate pointer).
@@ -1530,7 +1474,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Argument 9: Pass current isolate address.
__ LoadAddress(kScratchRegister,
- ExternalReference::isolate_address(masm->isolate()));
+ ExternalReference::isolate_address(isolate()));
__ movq(Operand(rsp, (argument_slots_on_stack - 1) * kRegisterSize),
kScratchRegister);
@@ -1556,8 +1500,8 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
#endif
// Argument 5: static offsets vector buffer.
- __ LoadAddress(r8,
- ExternalReference::address_of_static_offsets_vector(isolate));
+ __ LoadAddress(
+ r8, ExternalReference::address_of_static_offsets_vector(isolate()));
// Argument 5 passed in r8 on Linux and on the stack on Windows.
#ifdef _WIN64
__ movq(Operand(rsp, (argument_slots_on_stack - 5) * kRegisterSize), r8);
@@ -1682,8 +1626,8 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
kDontSaveFPRegs);
// Get the static offsets vector filled by the native regexp code.
- __ LoadAddress(rcx,
- ExternalReference::address_of_static_offsets_vector(isolate));
+ __ LoadAddress(
+ rcx, ExternalReference::address_of_static_offsets_vector(isolate()));
// rbx: last_match_info backing store (FixedArray)
// rcx: offsets vector
@@ -1716,7 +1660,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// haven't created the exception yet. Handle that in the runtime system.
// TODO(592): Rerunning the RegExp to get the stack overflow exception.
ExternalReference pending_exception_address(
- Isolate::kPendingExceptionAddress, isolate);
+ Isolate::kPendingExceptionAddress, isolate());
Operand pending_exception_operand =
masm->ExternalOperand(pending_exception_address, rbx);
__ movp(rax, pending_exception_operand);
@@ -1829,7 +1773,7 @@ static void BranchIfNotInternalizedString(MacroAssembler* masm,
void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
Label check_unequal_objects, done;
Condition cc = GetCondition();
- Factory* factory = masm->isolate()->factory();
+ Factory* factory = isolate()->factory();
Label miss;
CheckInputType(masm, rdx, left_, &miss);
@@ -2163,7 +2107,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
__ Push(rdx);
__ Push(rbx);
- CreateAllocationSiteStub create_stub;
+ CreateAllocationSiteStub create_stub(isolate);
__ CallStub(&create_stub);
__ Pop(rbx);
@@ -2197,14 +2141,77 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
}
+static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
+ // Do not transform the receiver for strict mode functions.
+ __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
+ __ testb(FieldOperand(rcx, SharedFunctionInfo::kStrictModeByteOffset),
+ Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte));
+ __ j(not_equal, cont);
+
+ // Do not transform the receiver for natives.
+ // SharedFunctionInfo is already loaded into rcx.
+ __ testb(FieldOperand(rcx, SharedFunctionInfo::kNativeByteOffset),
+ Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
+ __ j(not_equal, cont);
+}
+
+
+static void EmitSlowCase(Isolate* isolate,
+ MacroAssembler* masm,
+ StackArgumentsAccessor* args,
+ int argc,
+ Label* non_function) {
+ // Check for function proxy.
+ __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE);
+ __ j(not_equal, non_function);
+ __ PopReturnAddressTo(rcx);
+ __ Push(rdi); // put proxy as additional argument under return address
+ __ PushReturnAddressFrom(rcx);
+ __ Set(rax, argc + 1);
+ __ Set(rbx, 0);
+ __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY);
+ {
+ Handle<Code> adaptor =
+ masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
+ __ jmp(adaptor, RelocInfo::CODE_TARGET);
+ }
+
+ // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
+ // of the original receiver from the call site).
+ __ bind(non_function);
+ __ movp(args->GetReceiverOperand(), rdi);
+ __ Set(rax, argc);
+ __ Set(rbx, 0);
+ __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
+ Handle<Code> adaptor =
+ isolate->builtins()->ArgumentsAdaptorTrampoline();
+ __ Jump(adaptor, RelocInfo::CODE_TARGET);
+}
+
+
+static void EmitWrapCase(MacroAssembler* masm,
+ StackArgumentsAccessor* args,
+ Label* cont) {
+ // Wrap the receiver and patch it back onto the stack.
+ { FrameScope frame_scope(masm, StackFrame::INTERNAL);
+ __ Push(rdi);
+ __ Push(rax);
+ __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
+ __ Pop(rdi);
+ }
+ __ movp(args->GetReceiverOperand(), rax);
+ __ jmp(cont);
+}
+
+
void CallFunctionStub::Generate(MacroAssembler* masm) {
- // rbx : feedback vector
- // rdx : (only if rbx is not the megamorphic symbol) slot in feedback
- // vector (Smi)
// rdi : the function to call
+
+ // wrap_and_call can only be true if we are compiling a monomorphic method.
Isolate* isolate = masm->isolate();
Label slow, non_function, wrap, cont;
- StackArgumentsAccessor args(rsp, argc_);
+ int argc = argc_;
+ StackArgumentsAccessor args(rsp, argc);
if (NeedsChecks()) {
// Check that the function really is a JavaScript function.
@@ -2213,35 +2220,16 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// Goto slow case if we do not have a function.
__ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
__ j(not_equal, &slow);
-
- if (RecordCallTarget()) {
- GenerateRecordCallTarget(masm);
- // Type information was updated. Because we may call Array, which
- // expects either undefined or an AllocationSite in rbx we need
- // to set rbx to undefined.
- __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
- }
}
// Fast-case: Just invoke the function.
- ParameterCount actual(argc_);
+ ParameterCount actual(argc);
if (CallAsMethod()) {
if (NeedsChecks()) {
- // Do not transform the receiver for strict mode functions.
- __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
- __ testb(FieldOperand(rcx, SharedFunctionInfo::kStrictModeByteOffset),
- Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte));
- __ j(not_equal, &cont);
-
- // Do not transform the receiver for natives.
- // SharedFunctionInfo is already loaded into rcx.
- __ testb(FieldOperand(rcx, SharedFunctionInfo::kNativeByteOffset),
- Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
- __ j(not_equal, &cont);
+ EmitContinueIfStrictOrNative(masm, &cont);
}
-
// Load the receiver from the stack.
__ movp(rax, args.GetReceiverOperand());
@@ -2256,59 +2244,18 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
__ bind(&cont);
}
+
__ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper());
if (NeedsChecks()) {
// Slow-case: Non-function called.
__ bind(&slow);
- if (RecordCallTarget()) {
- // If there is a call target cache, mark it megamorphic in the
- // non-function case. MegamorphicSentinel is an immortal immovable
- // object (megamorphic symbol) so no write barrier is needed.
- __ SmiToInteger32(rdx, rdx);
- __ Move(FieldOperand(rbx, rdx, times_pointer_size,
- FixedArray::kHeaderSize),
- TypeFeedbackInfo::MegamorphicSentinel(isolate));
- __ Integer32ToSmi(rdx, rdx);
- }
- // Check for function proxy.
- __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE);
- __ j(not_equal, &non_function);
- __ PopReturnAddressTo(rcx);
- __ Push(rdi); // put proxy as additional argument under return address
- __ PushReturnAddressFrom(rcx);
- __ Set(rax, argc_ + 1);
- __ Set(rbx, 0);
- __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY);
- {
- Handle<Code> adaptor =
- masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
- __ jmp(adaptor, RelocInfo::CODE_TARGET);
- }
-
- // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
- // of the original receiver from the call site).
- __ bind(&non_function);
- __ movp(args.GetReceiverOperand(), rdi);
- __ Set(rax, argc_);
- __ Set(rbx, 0);
- __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
- Handle<Code> adaptor =
- isolate->builtins()->ArgumentsAdaptorTrampoline();
- __ Jump(adaptor, RelocInfo::CODE_TARGET);
+ EmitSlowCase(isolate, masm, &args, argc, &non_function);
}
if (CallAsMethod()) {
__ bind(&wrap);
- // Wrap the receiver and patch it back onto the stack.
- { FrameScope frame_scope(masm, StackFrame::INTERNAL);
- __ Push(rdi);
- __ Push(rax);
- __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
- __ Pop(rdi);
- }
- __ movp(args.GetReceiverOperand(), rax);
- __ jmp(&cont);
+ EmitWrapCase(masm, &args, &cont);
}
}
@@ -2374,11 +2321,125 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
__ bind(&do_call);
// Set expected number of arguments to zero (not changing rax).
__ Set(rbx, 0);
- __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+ __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET);
}
+static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
+ __ movp(vector, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
+ __ movp(vector, FieldOperand(vector, JSFunction::kSharedFunctionInfoOffset));
+ __ movp(vector, FieldOperand(vector,
+ SharedFunctionInfo::kFeedbackVectorOffset));
+}
+
+
+void CallICStub::Generate(MacroAssembler* masm) {
+ // rdi - function
+ // rbx - vector
+ // rdx - slot id
+ Isolate* isolate = masm->isolate();
+ Label extra_checks_or_miss, slow_start;
+ Label slow, non_function, wrap, cont;
+ Label have_js_function;
+ int argc = state_.arg_count();
+ StackArgumentsAccessor args(rsp, argc);
+ ParameterCount actual(argc);
+
+ EmitLoadTypeFeedbackVector(masm, rbx);
+
+ // The checks. First, does rdi match the recorded monomorphic target?
+ __ SmiToInteger32(rdx, rdx);
+ __ cmpq(rdi, FieldOperand(rbx, rdx, times_pointer_size,
+ FixedArray::kHeaderSize));
+ __ j(not_equal, &extra_checks_or_miss);
+
+ __ bind(&have_js_function);
+ if (state_.CallAsMethod()) {
+ EmitContinueIfStrictOrNative(masm, &cont);
+
+ // Load the receiver from the stack.
+ __ movp(rax, args.GetReceiverOperand());
+
+ __ JumpIfSmi(rax, &wrap);
+
+ __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
+ __ j(below, &wrap);
+
+ __ bind(&cont);
+ }
+
+ __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper());
+
+ __ bind(&slow);
+ EmitSlowCase(isolate, masm, &args, argc, &non_function);
+
+ if (state_.CallAsMethod()) {
+ __ bind(&wrap);
+ EmitWrapCase(masm, &args, &cont);
+ }
+
+ __ bind(&extra_checks_or_miss);
+ Label miss;
+
+ __ movp(rcx, FieldOperand(rbx, rdx, times_pointer_size,
+ FixedArray::kHeaderSize));
+ __ Cmp(rcx, TypeFeedbackInfo::MegamorphicSentinel(isolate));
+ __ j(equal, &slow_start);
+ __ Cmp(rcx, TypeFeedbackInfo::UninitializedSentinel(isolate));
+ __ j(equal, &miss);
+
+ if (!FLAG_trace_ic) {
+ // We are going megamorphic, and we don't want to visit the runtime.
+ __ Move(FieldOperand(rbx, rdx, times_pointer_size,
+ FixedArray::kHeaderSize),
+ TypeFeedbackInfo::MegamorphicSentinel(isolate));
+ __ jmp(&slow_start);
+ }
+
+ // We are here because tracing is on or we are going monomorphic.
+ __ bind(&miss);
+ GenerateMiss(masm);
+
+ // the slow case
+ __ bind(&slow_start);
+ // Check that function is not a smi.
+ __ JumpIfSmi(rdi, &non_function);
+ // Check that function is a JSFunction.
+ __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
+ __ j(not_equal, &slow);
+ __ jmp(&have_js_function);
+
+ // Unreachable
+ __ int3();
+}
+
+
+void CallICStub::GenerateMiss(MacroAssembler* masm) {
+ // Get the receiver of the function from the stack; 1 ~ return address.
+ __ movp(rcx, Operand(rsp, (state_.arg_count() + 1) * kPointerSize));
+
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+
+ // Push the receiver and the function and feedback info.
+ __ Push(rcx);
+ __ Push(rdi);
+ __ Push(rbx);
+ __ Integer32ToSmi(rdx, rdx);
+ __ Push(rdx);
+
+ // Call the entry.
+ ExternalReference miss = ExternalReference(IC_Utility(IC::kCallIC_Miss),
+ masm->isolate());
+ __ CallExternalReference(miss, 4);
+
+ // Move result to edi and exit the internal frame.
+ __ movp(rdi, rax);
+ }
+}
+
+
bool CEntryStub::NeedsImmovableCode() {
return false;
}
@@ -2401,26 +2462,35 @@ void CodeStub::GenerateFPStubs(Isolate* isolate) {
void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
- CEntryStub stub(1, kDontSaveFPRegs);
- stub.GetCode(isolate);
- CEntryStub save_doubles(1, kSaveFPRegs);
- save_doubles.GetCode(isolate);
+ CEntryStub stub(isolate, 1, kDontSaveFPRegs);
+ stub.GetCode();
+ CEntryStub save_doubles(isolate, 1, kSaveFPRegs);
+ save_doubles.GetCode();
}
-void CEntryStub::GenerateCore(MacroAssembler* masm,
- Label* throw_normal_exception,
- Label* throw_termination_exception,
- bool do_gc,
- bool always_allocate_scope) {
- // rax: result parameter for PerformGC, if any.
- // rbx: pointer to C function (C callee-saved).
- // rbp: frame pointer (restored after C call).
- // rsp: stack pointer (restored after C call).
+void CEntryStub::Generate(MacroAssembler* masm) {
+ // rax: number of arguments including receiver
+ // rbx: pointer to C function (C callee-saved)
+ // rbp: frame pointer of calling JS frame (restored after C call)
+ // rsp: stack pointer (restored after C call)
+ // rsi: current context (restored)
+
+ ProfileEntryHookStub::MaybeCallEntryHook(masm);
+
+ // Enter the exit frame that transitions from JavaScript to C++.
+#ifdef _WIN64
+ int arg_stack_space = (result_size_ < 2 ? 2 : 4);
+#else
+ int arg_stack_space = 0;
+#endif
+ __ EnterExitFrame(arg_stack_space, save_doubles_);
+
+ // rbx: pointer to builtin function (C callee-saved).
+ // rbp: frame pointer of exit frame (restored after C call).
+ // rsp: stack pointer (restored after C call).
// r14: number of arguments including receiver (C callee-saved).
- // r15: pointer to the first argument (C callee-saved).
- // This pointer is reused in LeaveExitFrame(), so it is stored in a
- // callee-saved register.
+ // r15: argv pointer (C callee-saved).
// Simple results returned in rax (both AMD64 and Win64 calling conventions).
// Complex results must be written to address passed as first argument.
@@ -2431,25 +2501,6 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
__ CheckStackAlignment();
}
- if (do_gc) {
- // Pass failure code returned from last attempt as first argument to
- // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the
- // stack is known to be aligned. This function takes one argument which is
- // passed in register.
- __ Move(arg_reg_2, ExternalReference::isolate_address(masm->isolate()));
- __ movp(arg_reg_1, rax);
- __ Move(kScratchRegister,
- ExternalReference::perform_gc_function(masm->isolate()));
- __ call(kScratchRegister);
- }
-
- ExternalReference scope_depth =
- ExternalReference::heap_always_allocate_scope_depth(masm->isolate());
- if (always_allocate_scope) {
- Operand scope_depth_operand = masm->ExternalOperand(scope_depth);
- __ incl(scope_depth_operand);
- }
-
// Call C function.
#ifdef _WIN64
// Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9.
@@ -2460,7 +2511,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
// Return result in single register (rax).
__ movp(rcx, r14); // argc.
__ movp(rdx, r15); // argv.
- __ Move(r8, ExternalReference::isolate_address(masm->isolate()));
+ __ Move(r8, ExternalReference::isolate_address(isolate()));
} else {
ASSERT_EQ(2, result_size_);
// Pass a pointer to the result location as the first argument.
@@ -2468,26 +2519,18 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
// Pass a pointer to the Arguments object as the second argument.
__ movp(rdx, r14); // argc.
__ movp(r8, r15); // argv.
- __ Move(r9, ExternalReference::isolate_address(masm->isolate()));
+ __ Move(r9, ExternalReference::isolate_address(isolate()));
}
#else // _WIN64
// GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9.
__ movp(rdi, r14); // argc.
__ movp(rsi, r15); // argv.
- __ Move(rdx, ExternalReference::isolate_address(masm->isolate()));
+ __ Move(rdx, ExternalReference::isolate_address(isolate()));
#endif
__ call(rbx);
// Result is in rax - do not destroy this register!
- if (always_allocate_scope) {
- Operand scope_depth_operand = masm->ExternalOperand(scope_depth);
- __ decl(scope_depth_operand);
- }
-
- // Check for failure result.
- Label failure_returned;
- STATIC_ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0);
#ifdef _WIN64
// If return value is on the stack, pop it to registers.
if (result_size_ > 1) {
@@ -2499,121 +2542,65 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
__ movq(rdx, Operand(rsp, 7 * kRegisterSize));
}
#endif
- __ leap(rcx, Operand(rax, 1));
- // Lower 2 bits of rcx are 0 iff rax has failure tag.
- __ testl(rcx, Immediate(kFailureTagMask));
- __ j(zero, &failure_returned);
+
+ // Runtime functions should not return 'the hole'. Allowing it to escape may
+ // lead to crashes in the IC code later.
+ if (FLAG_debug_code) {
+ Label okay;
+ __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
+ __ j(not_equal, &okay, Label::kNear);
+ __ int3();
+ __ bind(&okay);
+ }
+
+ // Check result for exception sentinel.
+ Label exception_returned;
+ __ CompareRoot(rax, Heap::kExceptionRootIndex);
+ __ j(equal, &exception_returned);
+
+ ExternalReference pending_exception_address(
+ Isolate::kPendingExceptionAddress, isolate());
+
+ // Check that there is no pending exception, otherwise we
+ // should have returned the exception sentinel.
+ if (FLAG_debug_code) {
+ Label okay;
+ __ LoadRoot(r14, Heap::kTheHoleValueRootIndex);
+ Operand pending_exception_operand =
+ masm->ExternalOperand(pending_exception_address);
+ __ cmpp(r14, pending_exception_operand);
+ __ j(equal, &okay, Label::kNear);
+ __ int3();
+ __ bind(&okay);
+ }
// Exit the JavaScript to C++ exit frame.
__ LeaveExitFrame(save_doubles_);
__ ret(0);
- // Handling of failure.
- __ bind(&failure_returned);
-
- Label retry;
- // If the returned exception is RETRY_AFTER_GC continue at retry label
- STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0);
- __ testl(rax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize));
- __ j(zero, &retry, Label::kNear);
+ // Handling of exception.
+ __ bind(&exception_returned);
// Retrieve the pending exception.
- ExternalReference pending_exception_address(
- Isolate::kPendingExceptionAddress, masm->isolate());
Operand pending_exception_operand =
masm->ExternalOperand(pending_exception_address);
__ movp(rax, pending_exception_operand);
// Clear the pending exception.
- pending_exception_operand =
- masm->ExternalOperand(pending_exception_address);
__ LoadRoot(rdx, Heap::kTheHoleValueRootIndex);
__ movp(pending_exception_operand, rdx);
// Special handling of termination exceptions which are uncatchable
// by javascript code.
+ Label throw_termination_exception;
__ CompareRoot(rax, Heap::kTerminationExceptionRootIndex);
- __ j(equal, throw_termination_exception);
+ __ j(equal, &throw_termination_exception);
// Handle normal exception.
- __ jmp(throw_normal_exception);
-
- // Retry.
- __ bind(&retry);
-}
-
-
-void CEntryStub::Generate(MacroAssembler* masm) {
- // rax: number of arguments including receiver
- // rbx: pointer to C function (C callee-saved)
- // rbp: frame pointer of calling JS frame (restored after C call)
- // rsp: stack pointer (restored after C call)
- // rsi: current context (restored)
-
- // NOTE: Invocations of builtins may return failure objects
- // instead of a proper result. The builtin entry handles
- // this by performing a garbage collection and retrying the
- // builtin once.
-
- ProfileEntryHookStub::MaybeCallEntryHook(masm);
-
- // Enter the exit frame that transitions from JavaScript to C++.
-#ifdef _WIN64
- int arg_stack_space = (result_size_ < 2 ? 2 : 4);
-#else
- int arg_stack_space = 0;
-#endif
- __ EnterExitFrame(arg_stack_space, save_doubles_);
-
- // rax: Holds the context at this point, but should not be used.
- // On entry to code generated by GenerateCore, it must hold
- // a failure result if the collect_garbage argument to GenerateCore
- // is true. This failure result can be the result of code
- // generated by a previous call to GenerateCore. The value
- // of rax is then passed to Runtime::PerformGC.
- // rbx: pointer to builtin function (C callee-saved).
- // rbp: frame pointer of exit frame (restored after C call).
- // rsp: stack pointer (restored after C call).
- // r14: number of arguments including receiver (C callee-saved).
- // r15: argv pointer (C callee-saved).
-
- Label throw_normal_exception;
- Label throw_termination_exception;
-
- // Call into the runtime system.
- GenerateCore(masm,
- &throw_normal_exception,
- &throw_termination_exception,
- false,
- false);
-
- // Do space-specific GC and retry runtime call.
- GenerateCore(masm,
- &throw_normal_exception,
- &throw_termination_exception,
- true,
- false);
-
- // Do full GC and retry runtime call one final time.
- Failure* failure = Failure::InternalError();
- __ Move(rax, failure, Assembler::RelocInfoNone());
- GenerateCore(masm,
- &throw_normal_exception,
- &throw_termination_exception,
- true,
- true);
-
- { FrameScope scope(masm, StackFrame::MANUAL);
- __ PrepareCallCFunction(0);
- __ CallCFunction(
- ExternalReference::out_of_memory_function(masm->isolate()), 0);
- }
+ __ Throw(rax);
__ bind(&throw_termination_exception);
__ ThrowUncatchable(rax);
-
- __ bind(&throw_normal_exception);
- __ Throw(rax);
}
@@ -2669,17 +2656,15 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
__ InitializeRootRegister();
}
- Isolate* isolate = masm->isolate();
-
// Save copies of the top frame descriptor on the stack.
- ExternalReference c_entry_fp(Isolate::kCEntryFPAddress, isolate);
+ ExternalReference c_entry_fp(Isolate::kCEntryFPAddress, isolate());
{
Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp);
__ Push(c_entry_fp_operand);
}
// If this is the outermost JS call, set js_entry_sp value.
- ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate);
+ ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate());
__ Load(rax, js_entry_sp);
__ testp(rax, rax);
__ j(not_zero, &not_outermost_js);
@@ -2700,9 +2685,9 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// Caught exception: Store result (exception) in the pending exception
// field in the JSEnv and return a failure sentinel.
ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
- isolate);
+ isolate());
__ Store(pending_exception, rax);
- __ Move(rax, Failure::Exception(), Assembler::RelocInfoNone());
+ __ LoadRoot(rax, Heap::kExceptionRootIndex);
__ jmp(&exit);
// Invoke: Link this frame into the handler chain. There's only one
@@ -2724,10 +2709,10 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// at the time this code is generated.
if (is_construct) {
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
- isolate);
+ isolate());
__ Load(rax, construct_entry);
} else {
- ExternalReference entry(Builtins::kJSEntryTrampoline, isolate);
+ ExternalReference entry(Builtins::kJSEntryTrampoline, isolate());
__ Load(rax, entry);
}
__ leap(kScratchRegister, FieldOperand(rax, Code::kHeaderSize));
@@ -2800,17 +2785,19 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
// indicate that the value is not an instance.
static const int kOffsetToMapCheckValue = 2;
- static const int kOffsetToResultValue = 18;
+ static const int kOffsetToResultValue = kPointerSize == kInt64Size ? 18 : 14;
// The last 4 bytes of the instruction sequence
- // movq(rdi, FieldOperand(rax, HeapObject::kMapOffset))
+ // movp(rdi, FieldOperand(rax, HeapObject::kMapOffset))
// Move(kScratchRegister, Factory::the_hole_value())
// in front of the hole value address.
- static const unsigned int kWordBeforeMapCheckValue = 0xBA49FF78;
+ static const unsigned int kWordBeforeMapCheckValue =
+ kPointerSize == kInt64Size ? 0xBA49FF78 : 0xBA41FF78;
// The last 4 bytes of the instruction sequence
// __ j(not_equal, &cache_miss);
// __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
// before the offset of the hole value in the root array.
- static const unsigned int kWordBeforeResultValue = 0x458B4906;
+ static const unsigned int kWordBeforeResultValue =
+ kPointerSize == kInt64Size ? 0x458B4906 : 0x458B4106;
// Only the inline check flag is supported on X64.
ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck());
int extra_argument_offset = HasCallSiteInlineCheck() ? 1 : 0;
@@ -3121,7 +3108,8 @@ void StringHelper::GenerateCopyCharactersREP(MacroAssembler* masm,
// Copy from edi to esi using rep movs instruction.
__ movl(kScratchRegister, count);
- __ shr(count, Immediate(kPointerSizeLog2)); // Number of doublewords to copy.
+ // Number of doublewords to copy.
+ __ shrl(count, Immediate(kPointerSizeLog2));
__ repmovsp();
// Find number of bytes left.
@@ -3248,7 +3236,7 @@ void SubStringStub::Generate(MacroAssembler* masm) {
// Longer than original string's length or negative: unsafe arguments.
__ j(above, &runtime);
// Return original string.
- Counters* counters = masm->isolate()->counters();
+ Counters* counters = isolate()->counters();
__ IncrementCounter(counters->sub_string_native(), 1);
__ ret(SUB_STRING_ARGUMENT_COUNT * kPointerSize);
__ bind(&not_original_string);
@@ -3593,7 +3581,7 @@ void StringCompareStub::Generate(MacroAssembler* masm) {
__ cmpp(rdx, rax);
__ j(not_equal, &not_same, Label::kNear);
__ Move(rax, Smi::FromInt(EQUAL));
- Counters* counters = masm->isolate()->counters();
+ Counters* counters = isolate()->counters();
__ IncrementCounter(counters->string_compare_native(), 1);
__ ret(2 * kPointerSize);
@@ -3617,227 +3605,30 @@ void StringCompareStub::Generate(MacroAssembler* masm) {
}
-void ArrayPushStub::Generate(MacroAssembler* masm) {
- int argc = arguments_count();
-
- StackArgumentsAccessor args(rsp, argc);
- if (argc == 0) {
- // Noop, return the length.
- __ movp(rax, FieldOperand(rdx, JSArray::kLengthOffset));
- __ ret((argc + 1) * kPointerSize);
- return;
- }
-
- Isolate* isolate = masm->isolate();
-
- if (argc != 1) {
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- Label call_builtin, attempt_to_grow_elements, with_write_barrier;
-
- // Get the elements array of the object.
- __ movp(rdi, FieldOperand(rdx, JSArray::kElementsOffset));
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- // Check that the elements are in fast mode and writable.
- __ Cmp(FieldOperand(rdi, HeapObject::kMapOffset),
- isolate->factory()->fixed_array_map());
- __ j(not_equal, &call_builtin);
- }
-
- // Get the array's length into rax and calculate new length.
- __ SmiToInteger32(rax, FieldOperand(rdx, JSArray::kLengthOffset));
- STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue);
- __ addl(rax, Immediate(argc));
-
- // Get the elements' length into rcx.
- __ SmiToInteger32(rcx, FieldOperand(rdi, FixedArray::kLengthOffset));
-
- // Check if we could survive without allocation.
- __ cmpl(rax, rcx);
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- __ j(greater, &attempt_to_grow_elements);
-
- // Check if value is a smi.
- __ movp(rcx, args.GetArgumentOperand(1));
- __ JumpIfNotSmi(rcx, &with_write_barrier);
-
- // Store the value.
- __ movp(FieldOperand(rdi,
- rax,
- times_pointer_size,
- FixedArray::kHeaderSize - argc * kPointerSize),
- rcx);
- } else {
- __ j(greater, &call_builtin);
-
- __ movp(rcx, args.GetArgumentOperand(1));
- __ StoreNumberToDoubleElements(
- rcx, rdi, rax, xmm0, &call_builtin, argc * kDoubleSize);
- }
-
- // Save new length.
- __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
-
- __ Integer32ToSmi(rax, rax); // Return new length as smi.
- __ ret((argc + 1) * kPointerSize);
-
- if (IsFastDoubleElementsKind(elements_kind())) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ bind(&with_write_barrier);
-
- if (IsFastSmiElementsKind(elements_kind())) {
- if (FLAG_trace_elements_transitions) __ jmp(&call_builtin);
-
- __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset),
- isolate->factory()->heap_number_map());
- __ j(equal, &call_builtin);
-
- ElementsKind target_kind = IsHoleyElementsKind(elements_kind())
- ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
- __ movp(rbx, ContextOperand(rsi, Context::GLOBAL_OBJECT_INDEX));
- __ movp(rbx, FieldOperand(rbx, GlobalObject::kNativeContextOffset));
- __ movp(rbx, ContextOperand(rbx, Context::JS_ARRAY_MAPS_INDEX));
- const int header_size = FixedArrayBase::kHeaderSize;
- // Verify that the object can be transitioned in place.
- const int origin_offset = header_size + elements_kind() * kPointerSize;
- __ movp(rdi, FieldOperand(rbx, origin_offset));
- __ cmpp(rdi, FieldOperand(rdx, HeapObject::kMapOffset));
- __ j(not_equal, &call_builtin);
-
- const int target_offset = header_size + target_kind * kPointerSize;
- __ movp(rbx, FieldOperand(rbx, target_offset));
- ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
- masm, DONT_TRACK_ALLOCATION_SITE, NULL);
- __ movp(rdi, FieldOperand(rdx, JSArray::kElementsOffset));
- }
-
- // Save new length.
- __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
-
- // Store the value.
- __ leap(rdx, FieldOperand(rdi,
- rax, times_pointer_size,
- FixedArray::kHeaderSize - argc * kPointerSize));
- __ movp(Operand(rdx, 0), rcx);
-
- __ RecordWrite(rdi, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
-
- __ Integer32ToSmi(rax, rax); // Return new length as smi.
- __ ret((argc + 1) * kPointerSize);
-
- __ bind(&attempt_to_grow_elements);
- if (!FLAG_inline_new) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ movp(rbx, args.GetArgumentOperand(1));
- // Growing elements that are SMI-only requires special handling in case the
- // new element is non-Smi. For now, delegate to the builtin.
- Label no_fast_elements_check;
- __ JumpIfSmi(rbx, &no_fast_elements_check);
- __ movp(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
- __ CheckFastObjectElements(rcx, &call_builtin, Label::kFar);
- __ bind(&no_fast_elements_check);
-
- ExternalReference new_space_allocation_top =
- ExternalReference::new_space_allocation_top_address(isolate);
- ExternalReference new_space_allocation_limit =
- ExternalReference::new_space_allocation_limit_address(isolate);
-
- const int kAllocationDelta = 4;
- ASSERT(kAllocationDelta >= argc);
- // Load top.
- __ Load(rcx, new_space_allocation_top);
-
- // Check if it's the end of elements.
- __ leap(rdx, FieldOperand(rdi,
- rax, times_pointer_size,
- FixedArray::kHeaderSize - argc * kPointerSize));
- __ cmpp(rdx, rcx);
- __ j(not_equal, &call_builtin);
- __ addp(rcx, Immediate(kAllocationDelta * kPointerSize));
- Operand limit_operand = masm->ExternalOperand(new_space_allocation_limit);
- __ cmpp(rcx, limit_operand);
- __ j(above, &call_builtin);
-
- // We fit and could grow elements.
- __ Store(new_space_allocation_top, rcx);
-
- // Push the argument...
- __ movp(Operand(rdx, 0), rbx);
- // ... and fill the rest with holes.
- __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
- for (int i = 1; i < kAllocationDelta; i++) {
- __ movp(Operand(rdx, i * kPointerSize), kScratchRegister);
- }
-
- if (IsFastObjectElementsKind(elements_kind())) {
- // We know the elements array is in new space so we don't need the
- // remembered set, but we just pushed a value onto it so we may have to tell
- // the incremental marker to rescan the object that we just grew. We don't
- // need to worry about the holes because they are in old space and already
- // marked black.
- __ RecordWrite(rdi, rdx, rbx, kDontSaveFPRegs, OMIT_REMEMBERED_SET);
- }
-
- // Restore receiver to rdx as finish sequence assumes it's here.
- __ movp(rdx, args.GetReceiverOperand());
-
- // Increment element's and array's sizes.
- __ SmiAddConstant(FieldOperand(rdi, FixedArray::kLengthOffset),
- Smi::FromInt(kAllocationDelta));
-
- // Make new length a smi before returning it.
- __ Integer32ToSmi(rax, rax);
- __ movp(FieldOperand(rdx, JSArray::kLengthOffset), rax);
-
- __ ret((argc + 1) * kPointerSize);
-
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
-}
-
-
void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rdx : left
// -- rax : right
// -- rsp[0] : return address
// -----------------------------------
- Isolate* isolate = masm->isolate();
// Load rcx with the allocation site. We stick an undefined dummy value here
// and replace it with the real allocation site later when we instantiate this
// stub in BinaryOpICWithAllocationSiteStub::GetCodeCopyFromTemplate().
- __ Move(rcx, handle(isolate->heap()->undefined_value()));
+ __ Move(rcx, handle(isolate()->heap()->undefined_value()));
// Make sure that we actually patched the allocation site.
if (FLAG_debug_code) {
__ testb(rcx, Immediate(kSmiTagMask));
__ Assert(not_equal, kExpectedAllocationSite);
__ Cmp(FieldOperand(rcx, HeapObject::kMapOffset),
- isolate->factory()->allocation_site_map());
+ isolate()->factory()->allocation_site_map());
__ Assert(equal, kExpectedAllocationSite);
}
// Tail call into the stub that handles binary operations with allocation
// sites.
- BinaryOpWithAllocationSiteStub stub(state_);
+ BinaryOpWithAllocationSiteStub stub(isolate(), state_);
__ TailCallStub(&stub);
}
@@ -3883,7 +3674,7 @@ void ICCompareStub::GenerateNumbers(MacroAssembler* masm) {
// Load left and right operand.
Label done, left, left_smi, right_smi;
__ JumpIfSmi(rax, &right_smi, Label::kNear);
- __ CompareMap(rax, masm->isolate()->factory()->heap_number_map());
+ __ CompareMap(rax, isolate()->factory()->heap_number_map());
__ j(not_equal, &maybe_undefined1, Label::kNear);
__ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
__ jmp(&left, Label::kNear);
@@ -3893,7 +3684,7 @@ void ICCompareStub::GenerateNumbers(MacroAssembler* masm) {
__ bind(&left);
__ JumpIfSmi(rdx, &left_smi, Label::kNear);
- __ CompareMap(rdx, masm->isolate()->factory()->heap_number_map());
+ __ CompareMap(rdx, isolate()->factory()->heap_number_map());
__ j(not_equal, &maybe_undefined2, Label::kNear);
__ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
__ jmp(&done);
@@ -3918,13 +3709,13 @@ void ICCompareStub::GenerateNumbers(MacroAssembler* masm) {
__ bind(&unordered);
__ bind(&generic_stub);
- ICCompareStub stub(op_, CompareIC::GENERIC, CompareIC::GENERIC,
+ ICCompareStub stub(isolate(), op_, CompareIC::GENERIC, CompareIC::GENERIC,
CompareIC::GENERIC);
- __ jmp(stub.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
+ __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
__ bind(&maybe_undefined1);
if (Token::IsOrderedRelationalCompareOp(op_)) {
- __ Cmp(rax, masm->isolate()->factory()->undefined_value());
+ __ Cmp(rax, isolate()->factory()->undefined_value());
__ j(not_equal, &miss);
__ JumpIfSmi(rdx, &unordered);
__ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rcx);
@@ -3934,7 +3725,7 @@ void ICCompareStub::GenerateNumbers(MacroAssembler* masm) {
__ bind(&maybe_undefined2);
if (Token::IsOrderedRelationalCompareOp(op_)) {
- __ Cmp(rdx, masm->isolate()->factory()->undefined_value());
+ __ Cmp(rdx, isolate()->factory()->undefined_value());
__ j(equal, &unordered);
}
@@ -4160,7 +3951,7 @@ void ICCompareStub::GenerateMiss(MacroAssembler* masm) {
{
// Call the runtime system in a fresh internal frame.
ExternalReference miss =
- ExternalReference(IC_Utility(IC::kCompareIC_Miss), masm->isolate());
+ ExternalReference(IC_Utility(IC::kCompareIC_Miss), isolate());
FrameScope scope(masm, StackFrame::INTERNAL);
__ Push(rdx);
@@ -4233,7 +4024,8 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
__ bind(&good);
}
- NameDictionaryLookupStub stub(properties, r0, r0, NEGATIVE_LOOKUP);
+ NameDictionaryLookupStub stub(masm->isolate(), properties, r0, r0,
+ NEGATIVE_LOOKUP);
__ Push(Handle<Object>(name));
__ Push(Immediate(name->Hash()));
__ CallStub(&stub);
@@ -4283,7 +4075,8 @@ void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
__ j(equal, done);
}
- NameDictionaryLookupStub stub(elements, r0, r1, POSITIVE_LOOKUP);
+ NameDictionaryLookupStub stub(masm->isolate(), elements, r0, r1,
+ POSITIVE_LOOKUP);
__ Push(name);
__ movl(r0, FieldOperand(name, Name::kHashFieldOffset));
__ shrl(r0, Immediate(Name::kHashShift));
@@ -4344,7 +4137,7 @@ void NameDictionaryLookupStub::Generate(MacroAssembler* masm) {
times_pointer_size,
kElementsStartOffset - kHeapObjectTag));
- __ Cmp(scratch, masm->isolate()->factory()->undefined_value());
+ __ Cmp(scratch, isolate()->factory()->undefined_value());
__ j(equal, &not_in_dictionary);
// Stop if found the property.
@@ -4387,10 +4180,10 @@ void NameDictionaryLookupStub::Generate(MacroAssembler* masm) {
void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
Isolate* isolate) {
- StoreBufferOverflowStub stub1(kDontSaveFPRegs);
- stub1.GetCode(isolate);
- StoreBufferOverflowStub stub2(kSaveFPRegs);
- stub2.GetCode(isolate);
+ StoreBufferOverflowStub stub1(isolate, kDontSaveFPRegs);
+ stub1.GetCode();
+ StoreBufferOverflowStub stub2(isolate, kSaveFPRegs);
+ stub2.GetCode();
}
@@ -4489,14 +4282,13 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
// TODO(gc) Can we just set address arg2 in the beginning?
__ Move(arg_reg_2, address);
__ LoadAddress(arg_reg_3,
- ExternalReference::isolate_address(masm->isolate()));
+ ExternalReference::isolate_address(isolate()));
int argument_count = 3;
AllowExternalCallThatCantCauseGC scope(masm);
__ PrepareCallCFunction(argument_count);
__ CallCFunction(
- ExternalReference::incremental_marking_record_write_function(
- masm->isolate()),
+ ExternalReference::incremental_marking_record_write_function(isolate()),
argument_count);
regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode_);
}
@@ -4674,8 +4466,8 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
- CEntryStub ces(1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
- __ Call(ces.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
+ CEntryStub ces(isolate(), 1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
+ __ Call(ces.GetCode(), RelocInfo::CODE_TARGET);
int parameter_count_offset =
StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
__ movp(rbx, MemOperand(rbp, parameter_count_offset));
@@ -4691,7 +4483,7 @@ void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
if (masm->isolate()->function_entry_hook() != NULL) {
- ProfileEntryHookStub stub;
+ ProfileEntryHookStub stub(masm->isolate());
masm->CallStub(&stub);
}
}
@@ -4716,7 +4508,7 @@ void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
masm->PushCallerSaved(kSaveFPRegs, arg_reg_1, arg_reg_2);
// Call the entry hook function.
- __ Move(rax, FUNCTION_ADDR(masm->isolate()->function_entry_hook()),
+ __ Move(rax, FUNCTION_ADDR(isolate()->function_entry_hook()),
Assembler::RelocInfoNone());
AllowExternalCallThatCantCauseGC scope(masm);
@@ -4738,7 +4530,7 @@ template<class T>
static void CreateArrayDispatch(MacroAssembler* masm,
AllocationSiteOverrideMode mode) {
if (mode == DISABLE_ALLOCATION_SITES) {
- T stub(GetInitialFastElementsKind(), mode);
+ T stub(masm->isolate(), GetInitialFastElementsKind(), mode);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
int last_index = GetSequenceIndexFromFastElementsKind(
@@ -4748,7 +4540,7 @@ static void CreateArrayDispatch(MacroAssembler* masm,
ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
__ cmpl(rdx, Immediate(kind));
__ j(not_equal, &next);
- T stub(kind);
+ T stub(masm->isolate(), kind);
__ TailCallStub(&stub);
__ bind(&next);
}
@@ -4797,12 +4589,14 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
ElementsKind initial = GetInitialFastElementsKind();
ElementsKind holey_initial = GetHoleyElementsKind(initial);
- ArraySingleArgumentConstructorStub stub_holey(holey_initial,
+ ArraySingleArgumentConstructorStub stub_holey(masm->isolate(),
+ holey_initial,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub_holey);
__ bind(&normal_sequence);
- ArraySingleArgumentConstructorStub stub(initial,
+ ArraySingleArgumentConstructorStub stub(masm->isolate(),
+ initial,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
@@ -4832,7 +4626,7 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
__ cmpl(rdx, Immediate(kind));
__ j(not_equal, &next);
- ArraySingleArgumentConstructorStub stub(kind);
+ ArraySingleArgumentConstructorStub stub(masm->isolate(), kind);
__ TailCallStub(&stub);
__ bind(&next);
}
@@ -4851,11 +4645,11 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
TERMINAL_FAST_ELEMENTS_KIND);
for (int i = 0; i <= to_index; ++i) {
ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
- T stub(kind);
- stub.GetCode(isolate);
+ T stub(isolate, kind);
+ stub.GetCode();
if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
- T stub1(kind, DISABLE_ALLOCATION_SITES);
- stub1.GetCode(isolate);
+ T stub1(isolate, kind, DISABLE_ALLOCATION_SITES);
+ stub1.GetCode();
}
}
}
@@ -4876,12 +4670,12 @@ void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
for (int i = 0; i < 2; i++) {
// For internal arrays we only need a few things
- InternalArrayNoArgumentConstructorStub stubh1(kinds[i]);
- stubh1.GetCode(isolate);
- InternalArraySingleArgumentConstructorStub stubh2(kinds[i]);
- stubh2.GetCode(isolate);
- InternalArrayNArgumentsConstructorStub stubh3(kinds[i]);
- stubh3.GetCode(isolate);
+ InternalArrayNoArgumentConstructorStub stubh1(isolate, kinds[i]);
+ stubh1.GetCode();
+ InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]);
+ stubh2.GetCode();
+ InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]);
+ stubh3.GetCode();
}
}
@@ -4964,7 +4758,7 @@ void InternalArrayConstructorStub::GenerateCase(
__ testp(rax, rax);
__ j(not_zero, &not_zero_case);
- InternalArrayNoArgumentConstructorStub stub0(kind);
+ InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
__ TailCallStub(&stub0);
__ bind(&not_zero_case);
@@ -4980,16 +4774,16 @@ void InternalArrayConstructorStub::GenerateCase(
__ j(zero, &normal_sequence);
InternalArraySingleArgumentConstructorStub
- stub1_holey(GetHoleyElementsKind(kind));
+ stub1_holey(isolate(), GetHoleyElementsKind(kind));
__ TailCallStub(&stub1_holey);
}
__ bind(&normal_sequence);
- InternalArraySingleArgumentConstructorStub stub1(kind);
+ InternalArraySingleArgumentConstructorStub stub1(isolate(), kind);
__ TailCallStub(&stub1);
__ bind(&not_one_case);
- InternalArrayNArgumentsConstructorStub stubN(kind);
+ InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
__ TailCallStub(&stubN);
}
@@ -5024,7 +4818,7 @@ void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
__ movzxbp(rcx, FieldOperand(rcx, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ andp(rcx, Immediate(Map::kElementsKindMask));
- __ shr(rcx, Immediate(Map::kElementsKindShift));
+ __ shrp(rcx, Immediate(Map::kElementsKindShift));
if (FLAG_debug_code) {
Label done;
@@ -5105,7 +4899,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
__ Push(scratch);
// isolate
__ Move(scratch,
- ExternalReference::isolate_address(masm->isolate()));
+ ExternalReference::isolate_address(isolate()));
__ Push(scratch);
// holder
__ Push(holder);
@@ -5143,7 +4937,8 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
// v8::InvocationCallback's argument.
__ leap(arguments_arg, StackSpaceOperand(0));
- Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
+ ExternalReference thunk_ref =
+ ExternalReference::invoke_function_callback(isolate());
// Accessor for FunctionCallbackInfo and first js arg.
StackArgumentsAccessor args_from_rbp(rbp, FCA::kArgsLength + 1,
@@ -5155,7 +4950,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
is_store ? 0 : FCA::kArgsLength - FCA::kReturnValueOffset);
__ CallApiFunctionAndReturn(
api_function_address,
- thunk_address,
+ thunk_ref,
callback_arg,
argc + FCA::kArgsLength + 1,
return_value_operand,
@@ -5202,7 +4997,8 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
// could be used to pass arguments.
__ leap(accessor_info_arg, StackSpaceOperand(0));
- Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+ ExternalReference thunk_ref =
+ ExternalReference::invoke_accessor_getter_callback(isolate());
// It's okay if api_function_address == getter_arg
// but not accessor_info_arg or name_arg
@@ -5215,7 +5011,7 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
PropertyCallbackArguments::kArgsLength - 1 -
PropertyCallbackArguments::kReturnValueOffset);
__ CallApiFunctionAndReturn(api_function_address,
- thunk_address,
+ thunk_ref,
getter_arg,
kStackSpace,
return_value_operand,
diff --git a/deps/v8/src/x64/code-stubs-x64.h b/deps/v8/src/x64/code-stubs-x64.h
index 8c8ab691ac..2d6d21d0ab 100644
--- a/deps/v8/src/x64/code-stubs-x64.h
+++ b/deps/v8/src/x64/code-stubs-x64.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_X64_CODE_STUBS_X64_H_
#define V8_X64_CODE_STUBS_X64_H_
@@ -38,8 +15,8 @@ void ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code);
class StoreBufferOverflowStub: public PlatformCodeStub {
public:
- explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp)
- : save_doubles_(save_fp) { }
+ StoreBufferOverflowStub(Isolate* isolate, SaveFPRegsMode save_fp)
+ : PlatformCodeStub(isolate), save_doubles_(save_fp) { }
void Generate(MacroAssembler* masm);
@@ -86,7 +63,7 @@ class StringHelper : public AllStatic {
class SubStringStub: public PlatformCodeStub {
public:
- SubStringStub() {}
+ explicit SubStringStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
private:
Major MajorKey() { return SubString; }
@@ -98,7 +75,7 @@ class SubStringStub: public PlatformCodeStub {
class StringCompareStub: public PlatformCodeStub {
public:
- StringCompareStub() {}
+ explicit StringCompareStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
// Compares two flat ASCII strings and returns result in rax.
static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
@@ -137,11 +114,16 @@ class NameDictionaryLookupStub: public PlatformCodeStub {
public:
enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
- NameDictionaryLookupStub(Register dictionary,
+ NameDictionaryLookupStub(Isolate* isolate,
+ Register dictionary,
Register result,
Register index,
LookupMode mode)
- : dictionary_(dictionary), result_(result), index_(index), mode_(mode) { }
+ : PlatformCodeStub(isolate),
+ dictionary_(dictionary),
+ result_(result),
+ index_(index),
+ mode_(mode) { }
void Generate(MacroAssembler* masm);
@@ -197,12 +179,14 @@ class NameDictionaryLookupStub: public PlatformCodeStub {
class RecordWriteStub: public PlatformCodeStub {
public:
- RecordWriteStub(Register object,
+ RecordWriteStub(Isolate* isolate,
+ Register object,
Register value,
Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode)
- : object_(object),
+ : PlatformCodeStub(isolate),
+ object_(object),
value_(value),
address_(address),
remembered_set_action_(remembered_set_action),
diff --git a/deps/v8/src/x64/codegen-x64.cc b/deps/v8/src/x64/codegen-x64.cc
index 9b92dc8673..9903017700 100644
--- a/deps/v8/src/x64/codegen-x64.cc
+++ b/deps/v8/src/x64/codegen-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -256,12 +233,20 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
__ CompareRoot(r8, Heap::kEmptyFixedArrayRootIndex);
__ j(equal, &only_change_map);
- // Check backing store for COW-ness. For COW arrays we have to
- // allocate a new backing store.
__ SmiToInteger32(r9, FieldOperand(r8, FixedDoubleArray::kLengthOffset));
- __ CompareRoot(FieldOperand(r8, HeapObject::kMapOffset),
- Heap::kFixedCOWArrayMapRootIndex);
- __ j(equal, &new_backing_store);
+ if (kPointerSize == kDoubleSize) {
+ // Check backing store for COW-ness. For COW arrays we have to
+ // allocate a new backing store.
+ __ CompareRoot(FieldOperand(r8, HeapObject::kMapOffset),
+ Heap::kFixedCOWArrayMapRootIndex);
+ __ j(equal, &new_backing_store);
+ } else {
+ // For x32 port we have to allocate a new backing store as SMI size is
+ // not equal with double size.
+ ASSERT(kDoubleSize == 2 * kPointerSize);
+ __ jmp(&new_backing_store);
+ }
+
// Check if the backing store is in new-space. If not, we need to allocate
// a new one since the old one is in pointer-space.
// If in new space, we can reuse the old backing store because it is
@@ -608,10 +593,10 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
__ movsd(result, Operand(kScratchRegister, 6 * kDoubleSize));
__ leaq(temp1, Operand(temp2, 0x1ff800));
__ andq(temp2, Immediate(0x7ff));
- __ shr(temp1, Immediate(11));
+ __ shrq(temp1, Immediate(11));
__ mulsd(double_scratch, Operand(kScratchRegister, 5 * kDoubleSize));
__ Move(kScratchRegister, ExternalReference::math_exp_log_table());
- __ shl(temp1, Immediate(52));
+ __ shlq(temp1, Immediate(52));
__ orq(temp1, Operand(kScratchRegister, temp2, times_8, 0));
__ Move(kScratchRegister, ExternalReference::math_exp_constants(0));
__ subsd(double_scratch, input);
@@ -631,37 +616,36 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
#undef __
-static byte* GetNoCodeAgeSequence(uint32_t* length) {
- static bool initialized = false;
- static byte sequence[kNoCodeAgeSequenceLength];
- *length = kNoCodeAgeSequenceLength;
- if (!initialized) {
- // The sequence of instructions that is patched out for aging code is the
- // following boilerplate stack-building prologue that is found both in
- // FUNCTION and OPTIMIZED_FUNCTION code:
- CodePatcher patcher(sequence, kNoCodeAgeSequenceLength);
- patcher.masm()->pushq(rbp);
- patcher.masm()->movp(rbp, rsp);
- patcher.masm()->Push(rsi);
- patcher.masm()->Push(rdi);
- initialized = true;
- }
- return sequence;
+CodeAgingHelper::CodeAgingHelper() {
+ ASSERT(young_sequence_.length() == kNoCodeAgeSequenceLength);
+ // The sequence of instructions that is patched out for aging code is the
+ // following boilerplate stack-building prologue that is found both in
+ // FUNCTION and OPTIMIZED_FUNCTION code:
+ CodePatcher patcher(young_sequence_.start(), young_sequence_.length());
+ patcher.masm()->pushq(rbp);
+ patcher.masm()->movp(rbp, rsp);
+ patcher.masm()->Push(rsi);
+ patcher.masm()->Push(rdi);
}
-bool Code::IsYoungSequence(byte* sequence) {
- uint32_t young_length;
- byte* young_sequence = GetNoCodeAgeSequence(&young_length);
- bool result = (!memcmp(sequence, young_sequence, young_length));
- ASSERT(result || *sequence == kCallOpcode);
+#ifdef DEBUG
+bool CodeAgingHelper::IsOld(byte* candidate) const {
+ return *candidate == kCallOpcode;
+}
+#endif
+
+
+bool Code::IsYoungSequence(Isolate* isolate, byte* sequence) {
+ bool result = isolate->code_aging_helper()->IsYoung(sequence);
+ ASSERT(result || isolate->code_aging_helper()->IsOld(sequence));
return result;
}
-void Code::GetCodeAgeAndParity(byte* sequence, Age* age,
+void Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
MarkingParity* parity) {
- if (IsYoungSequence(sequence)) {
+ if (IsYoungSequence(isolate, sequence)) {
*age = kNoAgeCodeAge;
*parity = NO_MARKING_PARITY;
} else {
@@ -678,10 +662,9 @@ void Code::PatchPlatformCodeAge(Isolate* isolate,
byte* sequence,
Code::Age age,
MarkingParity parity) {
- uint32_t young_length;
- byte* young_sequence = GetNoCodeAgeSequence(&young_length);
+ uint32_t young_length = isolate->code_aging_helper()->young_sequence_length();
if (age == kNoAgeCodeAge) {
- CopyBytes(sequence, young_sequence, young_length);
+ isolate->code_aging_helper()->CopyYoungSequenceTo(sequence);
CPU::FlushICache(sequence, young_length);
} else {
Code* stub = GetCodeAgeStub(isolate, age, parity);
diff --git a/deps/v8/src/x64/codegen-x64.h b/deps/v8/src/x64/codegen-x64.h
index e637ff0061..540bba77c8 100644
--- a/deps/v8/src/x64/codegen-x64.h
+++ b/deps/v8/src/x64/codegen-x64.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_X64_CODEGEN_X64_H_
#define V8_X64_CODEGEN_X64_H_
diff --git a/deps/v8/src/x64/cpu-x64.cc b/deps/v8/src/x64/cpu-x64.cc
index 4fa290a8b5..9243e2fb5e 100644
--- a/deps/v8/src/x64/cpu-x64.cc
+++ b/deps/v8/src/x64/cpu-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// CPU specific code for x64 independent of OS goes here.
@@ -41,16 +18,6 @@
namespace v8 {
namespace internal {
-void CPU::SetUp() {
- CpuFeatures::Probe();
-}
-
-
-bool CPU::SupportsCrankshaft() {
- return true; // Yay!
-}
-
-
void CPU::FlushICache(void* start, size_t size) {
// No need to flush the instruction cache on Intel. On Intel instruction
// cache flushing is only necessary when multiple cores running the same
diff --git a/deps/v8/src/x64/debug-x64.cc b/deps/v8/src/x64/debug-x64.cc
index 36d5df678e..6e0e05fda8 100644
--- a/deps/v8/src/x64/debug-x64.cc
+++ b/deps/v8/src/x64/debug-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -37,8 +14,6 @@
namespace v8 {
namespace internal {
-#ifdef ENABLE_DEBUGGER_SUPPORT
-
bool BreakLocationIterator::IsDebugBreakAtReturn() {
return Debug::IsDebugBreakAtReturn(rinfo());
}
@@ -50,7 +25,7 @@ bool BreakLocationIterator::IsDebugBreakAtReturn() {
void BreakLocationIterator::SetDebugBreakAtReturn() {
ASSERT(Assembler::kJSReturnSequenceLength >= Assembler::kCallSequenceLength);
rinfo()->PatchCodeWithCall(
- debug_info_->GetIsolate()->debug()->debug_break_return()->entry(),
+ debug_info_->GetIsolate()->builtins()->Return_DebugBreak()->entry(),
Assembler::kJSReturnSequenceLength - Assembler::kCallSequenceLength);
}
@@ -80,7 +55,7 @@ bool BreakLocationIterator::IsDebugBreakAtSlot() {
void BreakLocationIterator::SetDebugBreakAtSlot() {
ASSERT(IsDebugBreakSlot());
rinfo()->PatchCodeWithCall(
- debug_info_->GetIsolate()->debug()->debug_break_slot()->entry(),
+ debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry(),
Assembler::kDebugBreakSlotLength - Assembler::kCallSequenceLength);
}
@@ -124,7 +99,7 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
__ Push(reg);
}
if ((non_object_regs & (1 << r)) != 0) {
- __ PushInt64AsTwoSmis(reg);
+ __ PushRegisterAsTwoSmis(reg);
}
}
@@ -134,7 +109,7 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
__ Set(rax, 0); // No arguments (argc == 0).
__ Move(rbx, ExternalReference::debug_break(masm->isolate()));
- CEntryStub ceb(1);
+ CEntryStub ceb(masm->isolate(), 1);
__ CallStub(&ceb);
// Restore the register values from the expression stack.
@@ -149,7 +124,7 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
}
// Reconstruct the 64-bit value from two smis.
if ((non_object_regs & (1 << r)) != 0) {
- __ PopInt64AsTwoSmis(reg);
+ __ PopRegisterAsTwoSmis(reg);
}
}
@@ -177,6 +152,16 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
}
+void Debug::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
+ // Register state for CallICStub
+ // ----------- S t a t e -------------
+ // -- rdx : type feedback slot (smi)
+ // -- rdi : function
+ // -----------------------------------
+ Generate_DebugBreakCallHelper(masm, rdx.bit() | rdi.bit(), 0, false);
+}
+
+
void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Register state for IC load call (from ic-x64.cc).
// ----------- S t a t e -------------
@@ -230,15 +215,6 @@ void Debug::GenerateCompareNilICDebugBreak(MacroAssembler* masm) {
}
-void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) {
- // Register state for IC call call (from ic-x64.cc)
- // ----------- S t a t e -------------
- // -- rcx: function name
- // -----------------------------------
- Generate_DebugBreakCallHelper(masm, rcx.bit(), 0, false);
-}
-
-
void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
// Register state just before return from JS function (from codegen-x64.cc).
// ----------- S t a t e -------------
@@ -257,18 +233,6 @@ void Debug::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
}
-void Debug::GenerateCallFunctionStubRecordDebugBreak(MacroAssembler* masm) {
- // Register state for CallFunctionStub (from code-stubs-x64.cc).
- // ----------- S t a t e -------------
- // -- rdi : function
- // -- rbx: feedback array
- // -- rdx: slot in feedback array
- // -----------------------------------
- Generate_DebugBreakCallHelper(masm, rbx.bit() | rdx.bit() | rdi.bit(),
- 0, false);
-}
-
-
void Debug::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
// Register state for CallConstructStub (from code-stubs-x64.cc).
// rax is the actual number of arguments not encoded as a smi, see comment
@@ -348,8 +312,6 @@ const bool Debug::kFrameDropperSupported = true;
#undef __
-#endif // ENABLE_DEBUGGER_SUPPORT
-
} } // namespace v8::internal
#endif // V8_TARGET_ARCH_X64
diff --git a/deps/v8/src/x64/deoptimizer-x64.cc b/deps/v8/src/x64/deoptimizer-x64.cc
index 4bc644defe..9016d4b754 100644
--- a/deps/v8/src/x64/deoptimizer-x64.cc
+++ b/deps/v8/src/x64/deoptimizer-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -230,7 +207,7 @@ void Deoptimizer::EntryGenerator::Generate() {
// Fill in the input registers.
for (int i = kNumberOfRegisters -1; i >= 0; i--) {
int offset = (i * kPointerSize) + FrameDescription::registers_offset();
- __ Pop(Operand(rbx, offset));
+ __ PopQuad(Operand(rbx, offset));
}
// Fill in the double input registers.
@@ -307,13 +284,13 @@ void Deoptimizer::EntryGenerator::Generate() {
// Push state, pc, and continuation from the last output frame.
__ Push(Operand(rbx, FrameDescription::state_offset()));
- __ Push(Operand(rbx, FrameDescription::pc_offset()));
- __ Push(Operand(rbx, FrameDescription::continuation_offset()));
+ __ PushQuad(Operand(rbx, FrameDescription::pc_offset()));
+ __ PushQuad(Operand(rbx, FrameDescription::continuation_offset()));
// Push the registers from the last output frame.
for (int i = 0; i < kNumberOfRegisters; i++) {
int offset = (i * kPointerSize) + FrameDescription::registers_offset();
- __ Push(Operand(rbx, offset));
+ __ PushQuad(Operand(rbx, offset));
}
// Restore the registers from the stack.
@@ -352,11 +329,19 @@ void Deoptimizer::TableEntryGenerator::GeneratePrologue() {
void FrameDescription::SetCallerPc(unsigned offset, intptr_t value) {
+ if (kPCOnStackSize == 2 * kPointerSize) {
+ // Zero out the high-32 bit of PC for x32 port.
+ SetFrameSlot(offset + kPointerSize, 0);
+ }
SetFrameSlot(offset, value);
}
void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
+ if (kFPOnStackSize == 2 * kPointerSize) {
+ // Zero out the high-32 bit of FP for x32 port.
+ SetFrameSlot(offset + kPointerSize, 0);
+ }
SetFrameSlot(offset, value);
}
diff --git a/deps/v8/src/x64/disasm-x64.cc b/deps/v8/src/x64/disasm-x64.cc
index b870eae854..bef2f82dfa 100644
--- a/deps/v8/src/x64/disasm-x64.cc
+++ b/deps/v8/src/x64/disasm-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <assert.h>
#include <stdio.h>
diff --git a/deps/v8/src/x64/frames-x64.cc b/deps/v8/src/x64/frames-x64.cc
index 3154d80a60..7121d68cd3 100644
--- a/deps/v8/src/x64/frames-x64.cc
+++ b/deps/v8/src/x64/frames-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/x64/frames-x64.h b/deps/v8/src/x64/frames-x64.h
index 1fb77ffa6c..43c11961c3 100644
--- a/deps/v8/src/x64/frames-x64.h
+++ b/deps/v8/src/x64/frames-x64.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_X64_FRAMES_X64_H_
#define V8_X64_FRAMES_X64_H_
@@ -56,11 +33,12 @@ class EntryFrameConstants : public AllStatic {
static const int kXMMRegistersBlockSize =
kXMMRegisterSize * kCalleeSaveXMMRegisters;
static const int kCallerFPOffset =
- -10 * kPointerSize - kXMMRegistersBlockSize;
+ -3 * kPointerSize + -7 * kRegisterSize - kXMMRegistersBlockSize;
#else
- static const int kCallerFPOffset = -8 * kPointerSize;
+ // We have 3 Push and 5 pushq in the JSEntryStub::GenerateBody.
+ static const int kCallerFPOffset = -3 * kPointerSize + -5 * kRegisterSize;
#endif
- static const int kArgvOffset = 6 * kPointerSize;
+ static const int kArgvOffset = 6 * kPointerSize;
};
@@ -132,6 +110,10 @@ inline Object* JavaScriptFrame::function_slot_object() const {
inline void StackHandler::SetFp(Address slot, Address fp) {
+ if (kFPOnStackSize == 2 * kPointerSize) {
+ // Zero out the high-32 bit of FP for x32 port.
+ Memory::Address_at(slot + kPointerSize) = 0;
+ }
Memory::Address_at(slot) = fp;
}
diff --git a/deps/v8/src/x64/full-codegen-x64.cc b/deps/v8/src/x64/full-codegen-x64.cc
index f0b9438626..475080553a 100644
--- a/deps/v8/src/x64/full-codegen-x64.cc
+++ b/deps/v8/src/x64/full-codegen-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -74,7 +51,7 @@ class JumpPatchSite BASE_EMBEDDED {
void EmitPatchInfo() {
if (patch_site_.is_bound()) {
int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site_);
- ASSERT(is_int8(delta_to_patch_site));
+ ASSERT(is_uint8(delta_to_patch_site));
__ testl(rax, Immediate(delta_to_patch_site));
#ifdef DEBUG
info_emitted_ = true;
@@ -107,11 +84,15 @@ static void EmitStackCheck(MacroAssembler* masm_,
Isolate* isolate = masm_->isolate();
Label ok;
ASSERT(scratch.is(rsp) == (pointers == 0));
+ Heap::RootListIndex index;
if (pointers != 0) {
- __ movq(scratch, rsp);
- __ subq(scratch, Immediate(pointers * kPointerSize));
+ __ movp(scratch, rsp);
+ __ subp(scratch, Immediate(pointers * kPointerSize));
+ index = Heap::kRealStackLimitRootIndex;
+ } else {
+ index = Heap::kStackLimitRootIndex;
}
- __ CompareRoot(scratch, Heap::kStackLimitRootIndex);
+ __ CompareRoot(scratch, index);
__ j(above_equal, &ok, Label::kNear);
__ call(isolate->builtins()->StackCheck(), RelocInfo::CODE_TARGET);
__ bind(&ok);
@@ -136,8 +117,6 @@ void FullCodeGenerator::Generate() {
handler_table_ =
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
- InitializeFeedbackVector();
-
profiling_counter_ = isolate()->factory()->NewCell(
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
SetFunctionPosition(function());
@@ -195,7 +174,7 @@ void FullCodeGenerator::Generate() {
const int kMaxPushes = 32;
if (locals_count >= kMaxPushes) {
int loop_iterations = locals_count / kMaxPushes;
- __ movq(rcx, Immediate(loop_iterations));
+ __ movp(rcx, Immediate(loop_iterations));
Label loop_header;
__ bind(&loop_header);
// Do pushes.
@@ -203,7 +182,7 @@ void FullCodeGenerator::Generate() {
__ Push(rdx);
}
// Continue loop if not done.
- __ decq(rcx);
+ __ decp(rcx);
__ j(not_zero, &loop_header, Label::kNear);
}
int remaining = locals_count % kMaxPushes;
@@ -226,7 +205,7 @@ void FullCodeGenerator::Generate() {
__ Push(info->scope()->GetScopeInfo());
__ CallRuntime(Runtime::kHiddenNewGlobalContext, 2);
} else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
- FastNewContextStub stub(heap_slots);
+ FastNewContextStub stub(isolate(), heap_slots);
__ CallStub(&stub);
} else {
__ Push(rdi);
@@ -287,7 +266,7 @@ void FullCodeGenerator::Generate() {
} else {
type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
}
- ArgumentsAccessStub stub(type);
+ ArgumentsAccessStub stub(isolate(), type);
__ CallStub(&stub);
SetVar(arguments, rax, rbx, rdx);
@@ -359,6 +338,9 @@ void FullCodeGenerator::EmitProfilingCounterReset() {
}
+static const byte kJnsOffset = kPointerSize == kInt64Size ? 0x1d : 0x14;
+
+
void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
Label* back_edge_target) {
Comment cmnt(masm_, "[ Back edge bookkeeping");
@@ -369,17 +351,22 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
int weight = Min(kMaxBackEdgeWeight,
Max(1, distance / kCodeSizeMultiplier));
EmitProfilingCounterDecrement(weight);
- __ j(positive, &ok, Label::kNear);
- __ call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
- // Record a mapping of this PC offset to the OSR id. This is used to find
- // the AST id from the unoptimized code in order to use it as a key into
- // the deoptimization input data found in the optimized code.
- RecordBackEdge(stmt->OsrEntryId());
+ __ j(positive, &ok, Label::kNear);
+ {
+ PredictableCodeSizeScope predictible_code_size_scope(masm_, kJnsOffset);
+ DontEmitDebugCodeScope dont_emit_debug_code_scope(masm_);
+ __ call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
- EmitProfilingCounterReset();
+ // Record a mapping of this PC offset to the OSR id. This is used to find
+ // the AST id from the unoptimized code in order to use it as a key into
+ // the deoptimization input data found in the optimized code.
+ RecordBackEdge(stmt->OsrEntryId());
+ EmitProfilingCounterReset();
+ }
__ bind(&ok);
+
PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
// Record a mapping of the OSR id to this PC. This is used if the OSR
// entry becomes the target of a bailout. We don't expect it to be, but
@@ -432,11 +419,11 @@ void FullCodeGenerator::EmitReturnSequence() {
int arguments_bytes = (info_->scope()->num_parameters() + 1) * kPointerSize;
__ Ret(arguments_bytes, rcx);
-#ifdef ENABLE_DEBUGGER_SUPPORT
// Add padding that will be overwritten by a debugger breakpoint. We
- // have just generated at least 7 bytes: "movq rsp, rbp; pop rbp; ret k"
- // (3 + 1 + 3).
- const int kPadding = Assembler::kJSReturnSequenceLength - 7;
+ // have just generated at least 7 bytes: "movp rsp, rbp; pop rbp; ret k"
+ // (3 + 1 + 3) for x64 and at least 6 (2 + 1 + 3) bytes for x32.
+ const int kPadding = Assembler::kJSReturnSequenceLength -
+ kPointerSize == kInt64Size ? 7 : 6;
for (int i = 0; i < kPadding; ++i) {
masm_->int3();
}
@@ -444,7 +431,7 @@ void FullCodeGenerator::EmitReturnSequence() {
// for the debugger's requirements.
ASSERT(Assembler::kJSReturnSequenceLength <=
masm_->SizeOfCodeGeneratedSince(&check_exit_codesize));
-#endif
+
info_->AddNoFrameRange(no_frame_start, masm_->pc_offset());
}
}
@@ -1159,15 +1146,10 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Label non_proxy;
__ bind(&fixed_array);
- Handle<Object> feedback = Handle<Object>(
- Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
- isolate());
- StoreFeedbackVectorSlot(slot, feedback);
-
// No need for a write barrier, we are storing a Smi in the feedback vector.
__ Move(rbx, FeedbackVector());
__ Move(FieldOperand(rbx, FixedArray::OffsetOfElementAt(slot)),
- Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker));
+ TypeFeedbackInfo::MegamorphicSentinel(isolate()));
__ Move(rbx, Smi::FromInt(1)); // Smi indicates slow check
__ movp(rcx, Operand(rsp, 0 * kPointerSize)); // Get enumerated object
STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
@@ -1324,7 +1306,9 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
!pretenure &&
scope()->is_function_scope() &&
info->num_literals() == 0) {
- FastNewClosureStub stub(info->strict_mode(), info->is_generator());
+ FastNewClosureStub stub(isolate(),
+ info->strict_mode(),
+ info->is_generator());
__ Move(rbx, info);
__ CallStub(&stub);
} else {
@@ -1643,8 +1627,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
? ObjectLiteral::kHasFunction
: ObjectLiteral::kNoFlags;
int properties_count = constant_properties->length() / 2;
- if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() ||
- flags != ObjectLiteral::kFastElements ||
+ if (expr->may_store_doubles() || expr->depth() > 1 ||
+ Serializer::enabled(isolate()) || flags != ObjectLiteral::kFastElements ||
properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
__ movp(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
__ Push(FieldOperand(rdi, JSFunction::kLiteralsOffset));
@@ -1658,7 +1642,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
__ Move(rbx, Smi::FromInt(expr->literal_index()));
__ Move(rcx, constant_properties);
__ Move(rdx, Smi::FromInt(flags));
- FastCloneShallowObjectStub stub(properties_count);
+ FastCloneShallowObjectStub stub(isolate(), properties_count);
__ CallStub(&stub);
}
@@ -1793,11 +1777,12 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
__ Move(rbx, Smi::FromInt(expr->literal_index()));
__ Move(rcx, constant_elements);
FastCloneShallowArrayStub stub(
+ isolate(),
FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS,
allocation_site_mode,
length);
__ CallStub(&stub);
- } else if (expr->depth() > 1 || Serializer::enabled() ||
+ } else if (expr->depth() > 1 || Serializer::enabled(isolate()) ||
length > FastCloneShallowArrayStub::kMaximumClonedLength) {
__ movp(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
__ Push(FieldOperand(rbx, JSFunction::kLiteralsOffset));
@@ -1821,7 +1806,9 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
__ movp(rax, FieldOperand(rbx, JSFunction::kLiteralsOffset));
__ Move(rbx, Smi::FromInt(expr->literal_index()));
__ Move(rcx, constant_elements);
- FastCloneShallowArrayStub stub(mode, allocation_site_mode, length);
+ FastCloneShallowArrayStub stub(isolate(),
+ mode,
+ allocation_site_mode, length);
__ CallStub(&stub);
}
@@ -1858,7 +1845,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
} else {
// Store the subexpression value in the array's elements.
__ Move(rcx, Smi::FromInt(i));
- StoreArrayLiteralElementStub stub;
+ StoreArrayLiteralElementStub stub(isolate());
__ CallStub(&stub);
}
@@ -1875,7 +1862,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
void FullCodeGenerator::VisitAssignment(Assignment* expr) {
- ASSERT(expr->target()->IsValidLeftHandSide());
+ ASSERT(expr->target()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ Assignment");
@@ -2108,7 +2095,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
CallIC(ic, TypeFeedbackId::None());
__ movp(rdi, rax);
__ movp(Operand(rsp, 2 * kPointerSize), rdi);
- CallFunctionStub stub(1, CALL_AS_METHOD);
+ CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
__ CallStub(&stub);
__ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
@@ -2164,9 +2151,8 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
// Push holes for arguments to generator function.
__ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
- __ movsxlq(rdx,
- FieldOperand(rdx,
- SharedFunctionInfo::kFormalParameterCountOffset));
+ __ LoadSharedFunctionInfoSpecialField(rdx, rdx,
+ SharedFunctionInfo::kFormalParameterCountOffset);
__ LoadRoot(rcx, Heap::kTheHoleValueRootIndex);
Label push_argument_holes, push_frame;
__ bind(&push_argument_holes);
@@ -2252,7 +2238,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
Label gc_required;
Label allocated;
- Handle<Map> map(isolate()->native_context()->generator_result_map());
+ Handle<Map> map(isolate()->native_context()->iterator_result_map());
__ Allocate(map->instance_size(), rax, rcx, rdx, &gc_required, TAG_OBJECT);
__ jmp(&allocated);
@@ -2317,8 +2303,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ bind(&stub_call);
__ movp(rax, rcx);
- BinaryOpICStub stub(op, mode);
- CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
+ BinaryOpICStub stub(isolate(), op, mode);
+ CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done, Label::kNear);
@@ -2365,16 +2351,16 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode) {
__ Pop(rdx);
- BinaryOpICStub stub(op, mode);
+ BinaryOpICStub stub(isolate(), op, mode);
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
- CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
+ CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
context()->Plug(rax);
}
void FullCodeGenerator::EmitAssignment(Expression* expr) {
- ASSERT(expr->IsValidLeftHandSide());
+ ASSERT(expr->IsValidReferenceExpression());
// Left-hand side can only be a property, a global or a (parameter or local)
// slot.
@@ -2568,14 +2554,14 @@ void FullCodeGenerator::CallIC(Handle<Code> code,
// Code common for calls using the IC.
-void FullCodeGenerator::EmitCallWithIC(Call* expr) {
+void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
- ZoneList<Expression*>* args = expr->arguments();
- int arg_count = args->length();
- CallFunctionFlags flags;
- // Get the target function;
- if (callee->IsVariableProxy()) {
+ CallIC::CallType call_type = callee->IsVariableProxy()
+ ? CallIC::FUNCTION
+ : CallIC::METHOD;
+ // Get the target function.
+ if (call_type == CallIC::FUNCTION) {
{ StackValueContext context(this);
EmitVariableLoad(callee->AsVariableProxy());
PrepareForBailout(callee, NO_REGISTERS);
@@ -2583,7 +2569,6 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr) {
// Push undefined as receiver. This is patched in the method prologue if it
// is a sloppy mode method.
__ Push(isolate()->factory()->undefined_value());
- flags = NO_CALL_FUNCTION_FLAGS;
} else {
// Load the function from the receiver.
ASSERT(callee->IsProperty());
@@ -2593,40 +2578,19 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr) {
// Push the target function under the receiver.
__ Push(Operand(rsp, 0));
__ movp(Operand(rsp, kPointerSize), rax);
- flags = CALL_AS_METHOD;
- }
-
- // Load the arguments.
- { PreservePositionScope scope(masm()->positions_recorder());
- for (int i = 0; i < arg_count; i++) {
- VisitForStackValue(args->at(i));
- }
}
- // Record source position for debugger.
- SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, flags);
- __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
- __ CallStub(&stub);
-
- RecordJSReturnSite(expr);
-
- // Restore context register.
- __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
-
- context()->DropAndPlug(1, rax);
+ EmitCall(expr, call_type);
}
// Common code for calls using the IC.
-void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
- Expression* key) {
+void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
+ Expression* key) {
// Load the key.
VisitForAccumulatorValue(key);
Expression* callee = expr->expression();
- ZoneList<Expression*>* args = expr->arguments();
- int arg_count = args->length();
// Load the function from the receiver.
ASSERT(callee->IsProperty());
@@ -2638,29 +2602,12 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
__ Push(Operand(rsp, 0));
__ movp(Operand(rsp, kPointerSize), rax);
- // Load the arguments.
- { PreservePositionScope scope(masm()->positions_recorder());
- for (int i = 0; i < arg_count; i++) {
- VisitForStackValue(args->at(i));
- }
- }
-
- // Record source position for debugger.
- SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, CALL_AS_METHOD);
- __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
- __ CallStub(&stub);
-
- RecordJSReturnSite(expr);
- // Restore context register.
- __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
-
- context()->DropAndPlug(1, rax);
+ EmitCall(expr, CallIC::METHOD);
}
-void FullCodeGenerator::EmitCallWithStub(Call* expr) {
- // Code common for calls using the call stub.
+void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) {
+ // Load the arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope scope(masm()->positions_recorder());
@@ -2668,20 +2615,19 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr) {
VisitForStackValue(args->at(i));
}
}
- // Record source position for debugger.
- SetSourcePosition(expr->position());
- Handle<Object> uninitialized =
- TypeFeedbackInfo::UninitializedSentinel(isolate());
- StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
- __ Move(rbx, FeedbackVector());
+ // Record source position of the IC call.
+ SetSourcePosition(expr->position());
+ Handle<Code> ic = CallIC::initialize_stub(
+ isolate(), arg_count, call_type);
__ Move(rdx, Smi::FromInt(expr->CallFeedbackSlot()));
-
- // Record call targets in unoptimized code.
- CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
__ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
- __ CallStub(&stub);
+ // Don't assign a type feedback id to the IC, since type feedback is provided
+ // by the vector above.
+ CallIC(ic);
+
RecordJSReturnSite(expr);
+
// Restore context register.
__ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
// Discard the function left on TOS.
@@ -2750,7 +2696,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
}
// Record source position for debugger.
SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
+ CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
RecordJSReturnSite(expr);
@@ -2758,7 +2704,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
context()->DropAndPlug(1, rax);
} else if (call_type == Call::GLOBAL_CALL) {
- EmitCallWithIC(expr);
+ EmitCallWithLoadIC(expr);
} else if (call_type == Call::LOOKUP_SLOT_CALL) {
// Call to a lookup slot (dynamically introduced variable).
@@ -2795,16 +2741,16 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// The receiver is either the global receiver or an object found by
// LoadContextSlot.
- EmitCallWithStub(expr);
+ EmitCall(expr);
} else if (call_type == Call::PROPERTY_CALL) {
Property* property = callee->AsProperty();
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
if (property->key()->IsPropertyName()) {
- EmitCallWithIC(expr);
+ EmitCallWithLoadIC(expr);
} else {
- EmitKeyedCallWithIC(expr, property->key());
+ EmitKeyedCallWithLoadIC(expr, property->key());
}
} else {
ASSERT(call_type == Call::OTHER_CALL);
@@ -2814,7 +2760,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
}
__ PushRoot(Heap::kUndefinedValueRootIndex);
// Emit function call.
- EmitCallWithStub(expr);
+ EmitCall(expr);
}
#ifdef DEBUG
@@ -2851,12 +2797,8 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
__ movp(rdi, Operand(rsp, arg_count * kPointerSize));
// Record call targets in unoptimized code, but not in the snapshot.
- Handle<Object> uninitialized =
- TypeFeedbackInfo::UninitializedSentinel(isolate());
- StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
if (FLAG_pretenuring_call_new) {
- StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(),
- isolate()->factory()->NewAllocationSite());
+ EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
ASSERT(expr->AllocationSiteFeedbackSlot() ==
expr->CallNewFeedbackSlot() + 1);
}
@@ -2864,8 +2806,8 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
__ Move(rbx, FeedbackVector());
__ Move(rdx, Smi::FromInt(expr->CallNewFeedbackSlot()));
- CallConstructStub stub(RECORD_CALL_TARGET);
- __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
+ CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
+ __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
context()->Plug(rax);
}
@@ -3236,7 +3178,7 @@ void FullCodeGenerator::EmitArguments(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(0));
__ movp(rdx, rax);
__ Move(rax, Smi::FromInt(info_->scope()->num_parameters()));
- ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
+ ArgumentsAccessStub stub(isolate(), ArgumentsAccessStub::READ_ELEMENT);
__ CallStub(&stub);
context()->Plug(rax);
}
@@ -3326,30 +3268,9 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
}
-void FullCodeGenerator::EmitLog(CallRuntime* expr) {
- // Conditionally generate a log call.
- // Args:
- // 0 (literal string): The type of logging (corresponds to the flags).
- // This is used to determine whether or not to generate the log call.
- // 1 (string): Format string. Access the string at argument index 2
- // with '%2s' (see Logger::LogRuntime for all the formats).
- // 2 (array): Arguments to the format string.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT_EQ(args->length(), 3);
- if (CodeGenerator::ShouldGenerateLog(isolate(), args->at(0))) {
- VisitForStackValue(args->at(1));
- VisitForStackValue(args->at(2));
- __ CallRuntime(Runtime::kHiddenLog, 2);
- }
- // Finally, we're expected to leave a value on the top of the stack.
- __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
- context()->Plug(rax);
-}
-
-
void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
// Load the arguments on the stack and call the stub.
- SubStringStub stub;
+ SubStringStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 3);
VisitForStackValue(args->at(0));
@@ -3362,7 +3283,7 @@ void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) {
// Load the arguments on the stack and call the stub.
- RegExpExecStub stub;
+ RegExpExecStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 4);
VisitForStackValue(args->at(0));
@@ -3512,7 +3433,7 @@ void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
ASSERT(args->length() == 2);
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
- MathPowStub stub(MathPowStub::ON_STACK);
+ MathPowStub stub(isolate(), MathPowStub::ON_STACK);
__ CallStub(&stub);
context()->Plug(rax);
}
@@ -3553,7 +3474,7 @@ void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
// Load the argument into rax and call the stub.
VisitForAccumulatorValue(args->at(0));
- NumberToStringStub stub;
+ NumberToStringStub stub(isolate());
__ CallStub(&stub);
context()->Plug(rax);
}
@@ -3679,7 +3600,7 @@ void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) {
VisitForAccumulatorValue(args->at(1));
__ Pop(rdx);
- StringAddStub stub(STRING_ADD_CHECK_BOTH, NOT_TENURED);
+ StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED);
__ CallStub(&stub);
context()->Plug(rax);
}
@@ -3692,32 +3613,12 @@ void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
- StringCompareStub stub;
+ StringCompareStub stub(isolate());
__ CallStub(&stub);
context()->Plug(rax);
}
-void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_log, 1);
- context()->Plug(rax);
-}
-
-
-void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_sqrt, 1);
- context()->Plug(rax);
-}
-
-
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() >= 2);
@@ -3751,7 +3652,7 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
- RegExpConstructResultStub stub;
+ RegExpConstructResultStub stub(isolate());
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 3);
VisitForStackValue(args->at(0));
@@ -4177,7 +4078,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
// Record source position of the IC call.
SetSourcePosition(expr->position());
- CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
+ CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
@@ -4313,7 +4214,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
- ASSERT(expr->expression()->IsValidLeftHandSide());
+ ASSERT(expr->expression()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ CountOperation");
SetSourcePosition(expr->position());
@@ -4400,7 +4301,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ bind(&slow);
}
- ToNumberStub convert_stub;
+ ToNumberStub convert_stub(isolate());
__ CallStub(&convert_stub);
// Save result for postfix expressions.
@@ -4430,8 +4331,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ bind(&stub_call);
__ movp(rdx, rax);
__ Move(rax, Smi::FromInt(1));
- BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE);
- CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId());
+ BinaryOpICStub stub(isolate(), expr->binary_op(), NO_OVERWRITE);
+ CallIC(stub.GetCode(), expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
@@ -4546,12 +4447,13 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
}
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
- if (check->Equals(isolate()->heap()->number_string())) {
+ Factory* factory = isolate()->factory();
+ if (String::Equals(check, factory->number_string())) {
__ JumpIfSmi(rax, if_true);
__ movp(rax, FieldOperand(rax, HeapObject::kMapOffset));
__ CompareRoot(rax, Heap::kHeapNumberMapRootIndex);
Split(equal, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->string_string())) {
+ } else if (String::Equals(check, factory->string_string())) {
__ JumpIfSmi(rax, if_false);
// Check for undetectable objects => false.
__ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx);
@@ -4559,20 +4461,20 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ testb(FieldOperand(rdx, Map::kBitFieldOffset),
Immediate(1 << Map::kIsUndetectable));
Split(zero, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->symbol_string())) {
+ } else if (String::Equals(check, factory->symbol_string())) {
__ JumpIfSmi(rax, if_false);
__ CmpObjectType(rax, SYMBOL_TYPE, rdx);
Split(equal, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->boolean_string())) {
+ } else if (String::Equals(check, factory->boolean_string())) {
__ CompareRoot(rax, Heap::kTrueValueRootIndex);
__ j(equal, if_true);
__ CompareRoot(rax, Heap::kFalseValueRootIndex);
Split(equal, if_true, if_false, fall_through);
} else if (FLAG_harmony_typeof &&
- check->Equals(isolate()->heap()->null_string())) {
+ String::Equals(check, factory->null_string())) {
__ CompareRoot(rax, Heap::kNullValueRootIndex);
Split(equal, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->undefined_string())) {
+ } else if (String::Equals(check, factory->undefined_string())) {
__ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
__ j(equal, if_true);
__ JumpIfSmi(rax, if_false);
@@ -4581,14 +4483,14 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ testb(FieldOperand(rdx, Map::kBitFieldOffset),
Immediate(1 << Map::kIsUndetectable));
Split(not_zero, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->function_string())) {
+ } else if (String::Equals(check, factory->function_string())) {
__ JumpIfSmi(rax, if_false);
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
__ CmpObjectType(rax, JS_FUNCTION_TYPE, rdx);
__ j(equal, if_true);
__ CmpInstanceType(rdx, JS_FUNCTION_PROXY_TYPE);
Split(equal, if_true, if_false, fall_through);
- } else if (check->Equals(isolate()->heap()->object_string())) {
+ } else if (String::Equals(check, factory->object_string())) {
__ JumpIfSmi(rax, if_false);
if (!FLAG_harmony_typeof) {
__ CompareRoot(rax, Heap::kNullValueRootIndex);
@@ -4639,7 +4541,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
case Token::INSTANCEOF: {
VisitForStackValue(expr->right());
- InstanceofStub stub(InstanceofStub::kNoFlags);
+ InstanceofStub stub(isolate(), InstanceofStub::kNoFlags);
__ CallStub(&stub);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
__ testp(rax, rax);
@@ -4859,7 +4761,6 @@ FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
static const byte kJnsInstruction = 0x79;
-static const byte kJnsOffset = 0x1d;
static const byte kNopByteOne = 0x66;
static const byte kNopByteTwo = 0x90;
#ifdef DEBUG
diff --git a/deps/v8/src/x64/ic-x64.cc b/deps/v8/src/x64/ic-x64.cc
index ea118d0763..90a303dbae 100644
--- a/deps/v8/src/x64/ic-x64.cc
+++ b/deps/v8/src/x64/ic-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -421,9 +398,9 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
// based on 32 bits of the map pointer and the string hash.
__ movp(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
__ movl(rcx, rbx);
- __ shr(rcx, Immediate(KeyedLookupCache::kMapHashShift));
+ __ shrl(rcx, Immediate(KeyedLookupCache::kMapHashShift));
__ movl(rdi, FieldOperand(rax, String::kHashFieldOffset));
- __ shr(rdi, Immediate(String::kHashShift));
+ __ shrl(rdi, Immediate(String::kHashShift));
__ xorp(rcx, rdi);
int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask);
__ andp(rcx, Immediate(mask));
@@ -439,7 +416,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
for (int i = 0; i < kEntriesPerBucket - 1; i++) {
Label try_next_entry;
__ movp(rdi, rcx);
- __ shl(rdi, Immediate(kPointerSizeLog2 + 1));
+ __ shlp(rdi, Immediate(kPointerSizeLog2 + 1));
__ LoadAddress(kScratchRegister, cache_keys);
int off = kPointerSize * i * 2;
__ cmpp(rbx, Operand(kScratchRegister, rdi, times_1, off));
@@ -1303,7 +1280,7 @@ void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) {
Address delta_address = test_instruction_address + 1;
// The delta to the start of the map check instruction and the
// condition code uses at the patched jump.
- int8_t delta = *reinterpret_cast<int8_t*>(delta_address);
+ uint8_t delta = *reinterpret_cast<uint8_t*>(delta_address);
if (FLAG_trace_ic) {
PrintF("[ patching ic at %p, test=%p, delta=%d\n",
address, test_instruction_address, delta);
diff --git a/deps/v8/src/x64/lithium-codegen-x64.cc b/deps/v8/src/x64/lithium-codegen-x64.cc
index 894a4dd3a7..c3dc8ac30c 100644
--- a/deps/v8/src/x64/lithium-codegen-x64.cc
+++ b/deps/v8/src/x64/lithium-codegen-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -89,13 +66,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
PopulateDeoptimizationData(code);
- info()->CommitDependencies(code);
-}
-
-
-void LChunkBuilder::Abort(BailoutReason reason) {
- info()->set_bailout_reason(reason);
- status_ = ABORTED;
}
@@ -219,7 +189,7 @@ bool LCodeGen::GeneratePrologue() {
Comment(";;; Allocate local context");
// Argument to NewContext is the function, which is still in rdi.
if (heap_slots <= FastNewContextStub::kMaximumSlots) {
- FastNewContextStub stub(heap_slots);
+ FastNewContextStub stub(isolate(), heap_slots);
__ CallStub(&stub);
} else {
__ Push(rdi);
@@ -284,6 +254,12 @@ void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) {
+ if (FLAG_debug_code && FLAG_enable_slow_asserts && instr->HasResult() &&
+ instr->hydrogen_value()->representation().IsInteger32() &&
+ instr->result()->IsRegister()) {
+ __ AssertZeroExtended(ToRegister(instr->result()));
+ }
+
if (instr->HasResult() && instr->MustSignExtendResult(chunk())) {
if (instr->result()->IsRegister()) {
Register result_reg = ToRegister(instr->result());
@@ -687,6 +663,7 @@ void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment,
Safepoint::DeoptMode mode) {
+ environment->set_has_been_used();
if (!environment->HasBeenRegistered()) {
// Physical stack frame layout:
// -x ............. -4 0 ..................................... y
@@ -806,7 +783,7 @@ void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
int length = deoptimizations_.length();
if (length == 0) return;
Handle<DeoptimizationInputData> data =
- factory()->NewDeoptimizationInputData(length, TENURED);
+ DeoptimizationInputData::New(isolate(), length, TENURED);
Handle<ByteArray> translations =
translations_.CreateByteArray(isolate()->factory());
@@ -982,18 +959,18 @@ void LCodeGen::DoCallStub(LCallStub* instr) {
ASSERT(ToRegister(instr->result()).is(rax));
switch (instr->hydrogen()->major_key()) {
case CodeStub::RegExpExec: {
- RegExpExecStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ RegExpExecStub stub(isolate());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
case CodeStub::SubString: {
- SubStringStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ SubStringStub stub(isolate());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
case CodeStub::StringCompare: {
- StringCompareStub stub;
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ StringCompareStub stub(isolate());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
default:
@@ -1138,22 +1115,28 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
}
// If the divisor is negative, we have to negate and handle edge cases.
- Label not_kmin_int, done;
__ negl(dividend);
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
DeoptimizeIf(zero, instr->environment());
}
- if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
- // Note that we could emit branch-free code, but that would need one more
- // register.
- __ j(no_overflow, &not_kmin_int, Label::kNear);
- if (divisor == -1) {
- DeoptimizeIf(no_condition, instr->environment());
- } else {
- __ movl(dividend, Immediate(kMinInt / divisor));
- __ jmp(&done, Label::kNear);
- }
+
+ // If the negation could not overflow, simply shifting is OK.
+ if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
+ __ sarl(dividend, Immediate(shift));
+ return;
}
+
+ // Note that we could emit branch-free code, but that would need one more
+ // register.
+ if (divisor == -1) {
+ DeoptimizeIf(overflow, instr->environment());
+ return;
+ }
+
+ Label not_kmin_int, done;
+ __ j(no_overflow, &not_kmin_int, Label::kNear);
+ __ movl(dividend, Immediate(kMinInt / divisor));
+ __ jmp(&done, Label::kNear);
__ bind(&not_kmin_int);
__ sarl(dividend, Immediate(shift));
__ bind(&done);
@@ -1205,11 +1188,64 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
}
+// TODO(svenpanne) Refactor this to avoid code duplication with DoDivI.
+void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
+ HBinaryOperation* hdiv = instr->hydrogen();
+ Register dividend = ToRegister(instr->dividend());
+ Register divisor = ToRegister(instr->divisor());
+ Register remainder = ToRegister(instr->temp());
+ Register result = ToRegister(instr->result());
+ ASSERT(dividend.is(rax));
+ ASSERT(remainder.is(rdx));
+ ASSERT(result.is(rax));
+ ASSERT(!divisor.is(rax));
+ ASSERT(!divisor.is(rdx));
+
+ // Check for x / 0.
+ if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
+ __ testl(divisor, divisor);
+ DeoptimizeIf(zero, instr->environment());
+ }
+
+ // Check for (0 / -x) that will produce negative zero.
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ Label dividend_not_zero;
+ __ testl(dividend, dividend);
+ __ j(not_zero, &dividend_not_zero, Label::kNear);
+ __ testl(divisor, divisor);
+ DeoptimizeIf(sign, instr->environment());
+ __ bind(&dividend_not_zero);
+ }
+
+ // Check for (kMinInt / -1).
+ if (hdiv->CheckFlag(HValue::kCanOverflow)) {
+ Label dividend_not_min_int;
+ __ cmpl(dividend, Immediate(kMinInt));
+ __ j(not_zero, &dividend_not_min_int, Label::kNear);
+ __ cmpl(divisor, Immediate(-1));
+ DeoptimizeIf(zero, instr->environment());
+ __ bind(&dividend_not_min_int);
+ }
+
+ // Sign extend to rdx (= remainder).
+ __ cdq();
+ __ idivl(divisor);
+
+ Label done;
+ __ testl(remainder, remainder);
+ __ j(zero, &done, Label::kNear);
+ __ xorl(remainder, divisor);
+ __ sarl(remainder, Immediate(31));
+ __ addl(result, remainder);
+ __ bind(&done);
+}
+
+
void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
Register dividend = ToRegister(instr->dividend());
int32_t divisor = instr->divisor();
Register result = ToRegister(instr->result());
- ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor))));
+ ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor)));
ASSERT(!result.is(dividend));
// Check for (0 / -x) that will produce negative zero.
@@ -1261,7 +1297,7 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
}
__ TruncatingDiv(dividend, Abs(divisor));
- if (divisor < 0) __ negp(rdx);
+ if (divisor < 0) __ negl(rdx);
if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
__ movl(rax, rdx);
@@ -1272,15 +1308,15 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
}
+// TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI.
void LCodeGen::DoDivI(LDivI* instr) {
HBinaryOperation* hdiv = instr->hydrogen();
- Register dividend = ToRegister(instr->left());
- Register divisor = ToRegister(instr->right());
+ Register dividend = ToRegister(instr->dividend());
+ Register divisor = ToRegister(instr->divisor());
Register remainder = ToRegister(instr->temp());
- Register result = ToRegister(instr->result());
ASSERT(dividend.is(rax));
ASSERT(remainder.is(rdx));
- ASSERT(result.is(rax));
+ ASSERT(ToRegister(instr->result()).is(rax));
ASSERT(!divisor.is(rax));
ASSERT(!divisor.is(rdx));
@@ -1314,15 +1350,7 @@ void LCodeGen::DoDivI(LDivI* instr) {
__ cdq();
__ idivl(divisor);
- if (hdiv->IsMathFloorOfDiv()) {
- Label done;
- __ testl(remainder, remainder);
- __ j(zero, &done, Label::kNear);
- __ xorl(remainder, divisor);
- __ sarl(remainder, Immediate(31));
- __ addl(result, remainder);
- __ bind(&done);
- } else if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
+ if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
// Deoptimize if remainder is not 0.
__ testl(remainder, remainder);
DeoptimizeIf(not_zero, instr->environment());
@@ -1473,13 +1501,25 @@ void LCodeGen::DoBitI(LBitI* instr) {
} else if (right->IsStackSlot()) {
switch (instr->op()) {
case Token::BIT_AND:
- __ andp(ToRegister(left), ToOperand(right));
+ if (instr->IsInteger32()) {
+ __ andl(ToRegister(left), ToOperand(right));
+ } else {
+ __ andp(ToRegister(left), ToOperand(right));
+ }
break;
case Token::BIT_OR:
- __ orp(ToRegister(left), ToOperand(right));
+ if (instr->IsInteger32()) {
+ __ orl(ToRegister(left), ToOperand(right));
+ } else {
+ __ orp(ToRegister(left), ToOperand(right));
+ }
break;
case Token::BIT_XOR:
- __ xorp(ToRegister(left), ToOperand(right));
+ if (instr->IsInteger32()) {
+ __ xorl(ToRegister(left), ToOperand(right));
+ } else {
+ __ xorp(ToRegister(left), ToOperand(right));
+ }
break;
default:
UNREACHABLE();
@@ -1489,13 +1529,25 @@ void LCodeGen::DoBitI(LBitI* instr) {
ASSERT(right->IsRegister());
switch (instr->op()) {
case Token::BIT_AND:
- __ andp(ToRegister(left), ToRegister(right));
+ if (instr->IsInteger32()) {
+ __ andl(ToRegister(left), ToRegister(right));
+ } else {
+ __ andp(ToRegister(left), ToRegister(right));
+ }
break;
case Token::BIT_OR:
- __ orp(ToRegister(left), ToRegister(right));
+ if (instr->IsInteger32()) {
+ __ orl(ToRegister(left), ToRegister(right));
+ } else {
+ __ orp(ToRegister(left), ToRegister(right));
+ }
break;
case Token::BIT_XOR:
- __ xorp(ToRegister(left), ToRegister(right));
+ if (instr->IsInteger32()) {
+ __ xorl(ToRegister(left), ToRegister(right));
+ } else {
+ __ xorp(ToRegister(left), ToRegister(right));
+ }
break;
default:
UNREACHABLE();
@@ -1559,7 +1611,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
case Token::SHL:
if (shift_count != 0) {
if (instr->hydrogen_value()->representation().IsSmi()) {
- __ shl(ToRegister(left), Immediate(shift_count));
+ __ shlp(ToRegister(left), Immediate(shift_count));
} else {
__ shll(ToRegister(left), Immediate(shift_count));
}
@@ -1602,7 +1654,12 @@ void LCodeGen::DoSubI(LSubI* instr) {
void LCodeGen::DoConstantI(LConstantI* instr) {
- __ Set(ToRegister(instr->result()), instr->value());
+ Register dst = ToRegister(instr->result());
+ if (instr->value() == 0) {
+ __ xorl(dst, dst);
+ } else {
+ __ movl(dst, Immediate(instr->value()));
+ }
}
@@ -1634,8 +1691,16 @@ void LCodeGen::DoConstantE(LConstantE* instr) {
void LCodeGen::DoConstantT(LConstantT* instr) {
- Handle<Object> value = instr->value(isolate());
- __ Move(ToRegister(instr->result()), value);
+ Handle<Object> object = instr->value(isolate());
+ AllowDeferredHandleDereference smi_check;
+ if (instr->hydrogen()->HasObjectMap()) {
+ Handle<Map> object_map = instr->hydrogen()->ObjectMap().handle();
+ ASSERT(object->IsHeapObject());
+ ASSERT(!object_map->is_stable() ||
+ *object_map == Handle<HeapObject>::cast(object)->map());
+ USE(object_map);
+ }
+ __ Move(ToRegister(instr->result()), object);
}
@@ -1775,6 +1840,7 @@ void LCodeGen::DoAddI(LAddI* instr) {
if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
if (right->IsConstantOperand()) {
+ ASSERT(!target_rep.IsSmi()); // No support for smi-immediates.
int32_t offset = ToInteger32(LConstantOperand::cast(right));
if (is_p) {
__ leap(ToRegister(instr->result()),
@@ -1793,6 +1859,7 @@ void LCodeGen::DoAddI(LAddI* instr) {
}
} else {
if (right->IsConstantOperand()) {
+ ASSERT(!target_rep.IsSmi()); // No support for smi-immediates.
if (is_p) {
__ addp(ToRegister(left),
Immediate(ToInteger32(LConstantOperand::cast(right))));
@@ -1940,8 +2007,8 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
ASSERT(ToRegister(instr->right()).is(rax));
ASSERT(ToRegister(instr->result()).is(rax));
- BinaryOpICStub stub(instr->op(), NO_OVERWRITE);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
@@ -2534,10 +2601,10 @@ void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
ASSERT(ToRegister(instr->context()).is(rsi));
- InstanceofStub stub(InstanceofStub::kNoFlags);
+ InstanceofStub stub(isolate(), InstanceofStub::kNoFlags);
__ Push(ToRegister(instr->left()));
__ Push(ToRegister(instr->right()));
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
Label true_value, done;
__ testp(rax, rax);
__ j(zero, &true_value, Label::kNear);
@@ -2620,7 +2687,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
PushSafepointRegistersScope scope(this);
InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>(
InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck);
- InstanceofStub stub(flags);
+ InstanceofStub stub(isolate(), flags);
__ Push(ToRegister(instr->value()));
__ Push(instr->function());
@@ -2635,7 +2702,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
// safepoint with two arguments because stub is going to
// remove the third argument from the stack before jumping
// to instanceof builtin on the slow path.
- CallCodeGeneric(stub.GetCode(isolate()),
+ CallCodeGeneric(stub.GetCode(),
RelocInfo::CODE_TARGET,
instr,
RECORD_SAFEPOINT_WITH_REGISTERS,
@@ -2706,7 +2773,7 @@ void LCodeGen::DoReturn(LReturn* instr) {
__ SmiToInteger32(reg, reg);
Register return_addr_reg = reg.is(rcx) ? rbx : rcx;
__ PopReturnAddressTo(return_addr_reg);
- __ shl(reg, Immediate(kPointerSizeLog2));
+ __ shlp(reg, Immediate(kPointerSizeLog2));
__ addp(rsp, reg);
__ jmp(return_addr_reg);
}
@@ -2848,17 +2915,17 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
}
Representation representation = access.representation();
- if (representation.IsSmi() &&
+ if (representation.IsSmi() && SmiValuesAre32Bits() &&
instr->hydrogen()->representation().IsInteger32()) {
-#ifdef DEBUG
- Register scratch = kScratchRegister;
- __ Load(scratch, FieldOperand(object, offset), representation);
- __ AssertSmi(scratch);
-#endif
+ if (FLAG_debug_code) {
+ Register scratch = kScratchRegister;
+ __ Load(scratch, FieldOperand(object, offset), representation);
+ __ AssertSmi(scratch);
+ }
// Read int value directly from upper half of the smi.
STATIC_ASSERT(kSmiTag == 0);
- STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
+ ASSERT(kSmiTagSize + kSmiShiftSize == 32);
offset += kPointerSize / 2;
representation = Representation::Integer32();
}
@@ -2981,25 +3048,25 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
switch (elements_kind) {
case EXTERNAL_INT8_ELEMENTS:
case INT8_ELEMENTS:
- __ movsxbq(result, operand);
+ __ movsxbl(result, operand);
break;
case EXTERNAL_UINT8_ELEMENTS:
case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
case UINT8_ELEMENTS:
case UINT8_CLAMPED_ELEMENTS:
- __ movzxbp(result, operand);
+ __ movzxbl(result, operand);
break;
case EXTERNAL_INT16_ELEMENTS:
case INT16_ELEMENTS:
- __ movsxwq(result, operand);
+ __ movsxwl(result, operand);
break;
case EXTERNAL_UINT16_ELEMENTS:
case UINT16_ELEMENTS:
- __ movzxwp(result, operand);
+ __ movzxwl(result, operand);
break;
case EXTERNAL_INT32_ELEMENTS:
case INT32_ELEMENTS:
- __ movsxlq(result, operand);
+ __ movl(result, operand);
break;
case EXTERNAL_UINT32_ELEMENTS:
case UINT32_ELEMENTS:
@@ -3062,23 +3129,23 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
int offset = FixedArray::kHeaderSize - kHeapObjectTag;
Representation representation = hinstr->representation();
- if (representation.IsInteger32() &&
+ if (representation.IsInteger32() && SmiValuesAre32Bits() &&
hinstr->elements_kind() == FAST_SMI_ELEMENTS) {
ASSERT(!requires_hole_check);
-#ifdef DEBUG
- Register scratch = kScratchRegister;
- __ Load(scratch,
- BuildFastArrayOperand(instr->elements(),
- key,
- FAST_ELEMENTS,
- offset,
- instr->additional_index()),
- Representation::Smi());
- __ AssertSmi(scratch);
-#endif
+ if (FLAG_debug_code) {
+ Register scratch = kScratchRegister;
+ __ Load(scratch,
+ BuildFastArrayOperand(instr->elements(),
+ key,
+ FAST_ELEMENTS,
+ offset,
+ instr->additional_index()),
+ Representation::Smi());
+ __ AssertSmi(scratch);
+ }
// Read int value directly from upper half of the smi.
STATIC_ASSERT(kSmiTag == 0);
- STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
+ ASSERT(kSmiTagSize + kSmiShiftSize == 32);
offset += kPointerSize / 2;
}
@@ -3470,8 +3537,8 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
__ bind(&allocated);
__ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset));
- __ shl(tmp2, Immediate(1));
- __ shr(tmp2, Immediate(1));
+ __ shlq(tmp2, Immediate(1));
+ __ shrq(tmp2, Immediate(1));
__ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2);
__ StoreToSafepointRegisterSlot(input_reg, tmp);
@@ -3573,7 +3640,7 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) {
__ testq(output_reg, Immediate(1));
DeoptimizeIf(not_zero, instr->environment());
__ Set(output_reg, 0);
- __ jmp(&done, Label::kNear);
+ __ jmp(&done);
__ bind(&positive_sign);
}
@@ -3713,7 +3780,7 @@ void LCodeGen::DoPower(LPower* instr) {
ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
if (exponent_type.IsSmi()) {
- MathPowStub stub(MathPowStub::TAGGED);
+ MathPowStub stub(isolate(), MathPowStub::TAGGED);
__ CallStub(&stub);
} else if (exponent_type.IsTagged()) {
Label no_deopt;
@@ -3721,14 +3788,14 @@ void LCodeGen::DoPower(LPower* instr) {
__ CmpObjectType(exponent, HEAP_NUMBER_TYPE, rcx);
DeoptimizeIf(not_equal, instr->environment());
__ bind(&no_deopt);
- MathPowStub stub(MathPowStub::TAGGED);
+ MathPowStub stub(isolate(), MathPowStub::TAGGED);
__ CallStub(&stub);
} else if (exponent_type.IsInteger32()) {
- MathPowStub stub(MathPowStub::INTEGER);
+ MathPowStub stub(isolate(), MathPowStub::INTEGER);
__ CallStub(&stub);
} else {
ASSERT(exponent_type.IsDouble());
- MathPowStub stub(MathPowStub::DOUBLE);
+ MathPowStub stub(isolate(), MathPowStub::DOUBLE);
__ CallStub(&stub);
}
}
@@ -3819,8 +3886,8 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
ASSERT(ToRegister(instr->result()).is(rax));
int arity = instr->arity();
- CallFunctionStub stub(arity, instr->hydrogen()->function_flags());
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
@@ -3832,8 +3899,8 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
__ Set(rax, instr->arity());
// No cell in ebx for construct type feedback in optimized code
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
- CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
}
@@ -3851,8 +3918,8 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
: DONT_OVERRIDE;
if (instr->arity() == 0) {
- ArrayNoArgumentConstructorStub stub(kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
} else if (instr->arity() == 1) {
Label done;
if (IsFastPackedElementsKind(kind)) {
@@ -3864,18 +3931,20 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
__ j(zero, &packed_case, Label::kNear);
ElementsKind holey_kind = GetHoleyElementsKind(kind);
- ArraySingleArgumentConstructorStub stub(holey_kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArraySingleArgumentConstructorStub stub(isolate(),
+ holey_kind,
+ override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
__ jmp(&done, Label::kNear);
__ bind(&packed_case);
}
- ArraySingleArgumentConstructorStub stub(kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
__ bind(&done);
} else {
- ArrayNArgumentsConstructorStub stub(kind, override_mode);
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
+ ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode);
+ CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
}
}
@@ -3929,7 +3998,6 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
}
Register object = ToRegister(instr->object());
- Handle<Map> transition = instr->transition();
SmiCheck check_needed = hinstr->value()->IsHeapObject()
? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
@@ -3948,20 +4016,22 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
Condition cc = masm()->CheckSmi(value);
DeoptimizeIf(cc, instr->environment());
- // We know that value is a smi now, so we can omit the check below.
+ // We know now that value is not a smi, so we can omit the check below.
check_needed = OMIT_SMI_CHECK;
}
}
} else if (representation.IsDouble()) {
- ASSERT(transition.is_null());
ASSERT(access.IsInobject());
+ ASSERT(!hinstr->has_transition());
ASSERT(!hinstr->NeedsWriteBarrier());
XMMRegister value = ToDoubleRegister(instr->value());
__ movsd(FieldOperand(object, offset), value);
return;
}
- if (!transition.is_null()) {
+ if (hinstr->has_transition()) {
+ Handle<Map> transition = hinstr->transition_map();
+ AddDeprecationDependency(transition);
if (!hinstr->NeedsWriteBarrierForMap()) {
__ Move(FieldOperand(object, HeapObject::kMapOffset), transition);
} else {
@@ -3986,17 +4056,17 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
__ movp(write_register, FieldOperand(object, JSObject::kPropertiesOffset));
}
- if (representation.IsSmi() &&
+ if (representation.IsSmi() && SmiValuesAre32Bits() &&
hinstr->value()->representation().IsInteger32()) {
ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY);
-#ifdef DEBUG
- Register scratch = kScratchRegister;
- __ Load(scratch, FieldOperand(write_register, offset), representation);
- __ AssertSmi(scratch);
-#endif
+ if (FLAG_debug_code) {
+ Register scratch = kScratchRegister;
+ __ Load(scratch, FieldOperand(write_register, offset), representation);
+ __ AssertSmi(scratch);
+ }
// Store int value directly to upper half of the smi.
STATIC_ASSERT(kSmiTag == 0);
- STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
+ ASSERT(kSmiTagSize + kSmiShiftSize == 32);
offset += kPointerSize / 2;
representation = Representation::Integer32();
}
@@ -4051,65 +4121,64 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
}
-void LCodeGen::ApplyCheckIf(Condition cc, LBoundsCheck* check) {
- if (FLAG_debug_code && check->hydrogen()->skip_check()) {
- Label done;
- __ j(NegateCondition(cc), &done, Label::kNear);
- __ int3();
- __ bind(&done);
- } else {
- DeoptimizeIf(cc, check->environment());
- }
-}
-
-
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
- HBoundsCheck* hinstr = instr->hydrogen();
- if (hinstr->skip_check()) return;
-
- Representation representation = hinstr->length()->representation();
- ASSERT(representation.Equals(hinstr->index()->representation()));
+ Representation representation = instr->hydrogen()->length()->representation();
+ ASSERT(representation.Equals(instr->hydrogen()->index()->representation()));
ASSERT(representation.IsSmiOrInteger32());
- if (instr->length()->IsRegister()) {
- Register reg = ToRegister(instr->length());
-
- if (instr->index()->IsConstantOperand()) {
- int32_t constant_index =
- ToInteger32(LConstantOperand::cast(instr->index()));
+ Condition cc = instr->hydrogen()->allow_equality() ? below : below_equal;
+ if (instr->length()->IsConstantOperand()) {
+ int32_t length = ToInteger32(LConstantOperand::cast(instr->length()));
+ Register index = ToRegister(instr->index());
+ if (representation.IsSmi()) {
+ __ Cmp(index, Smi::FromInt(length));
+ } else {
+ __ cmpl(index, Immediate(length));
+ }
+ cc = ReverseCondition(cc);
+ } else if (instr->index()->IsConstantOperand()) {
+ int32_t index = ToInteger32(LConstantOperand::cast(instr->index()));
+ if (instr->length()->IsRegister()) {
+ Register length = ToRegister(instr->length());
if (representation.IsSmi()) {
- __ Cmp(reg, Smi::FromInt(constant_index));
+ __ Cmp(length, Smi::FromInt(index));
} else {
- __ cmpl(reg, Immediate(constant_index));
+ __ cmpl(length, Immediate(index));
}
} else {
- Register reg2 = ToRegister(instr->index());
+ Operand length = ToOperand(instr->length());
if (representation.IsSmi()) {
- __ cmpp(reg, reg2);
+ __ Cmp(length, Smi::FromInt(index));
} else {
- __ cmpl(reg, reg2);
+ __ cmpl(length, Immediate(index));
}
}
} else {
- Operand length = ToOperand(instr->length());
- if (instr->index()->IsConstantOperand()) {
- int32_t constant_index =
- ToInteger32(LConstantOperand::cast(instr->index()));
+ Register index = ToRegister(instr->index());
+ if (instr->length()->IsRegister()) {
+ Register length = ToRegister(instr->length());
if (representation.IsSmi()) {
- __ Cmp(length, Smi::FromInt(constant_index));
+ __ cmpp(length, index);
} else {
- __ cmpl(length, Immediate(constant_index));
+ __ cmpl(length, index);
}
} else {
+ Operand length = ToOperand(instr->length());
if (representation.IsSmi()) {
- __ cmpp(length, ToRegister(instr->index()));
+ __ cmpp(length, index);
} else {
- __ cmpl(length, ToRegister(instr->index()));
+ __ cmpl(length, index);
}
}
}
- Condition condition = hinstr->allow_equality() ? below : below_equal;
- ApplyCheckIf(condition, instr);
+ if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
+ Label done;
+ __ j(NegateCondition(cc), &done, Label::kNear);
+ __ int3();
+ __ bind(&done);
+ } else {
+ DeoptimizeIf(cc, instr->environment());
+ }
}
@@ -4209,23 +4278,23 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
int offset = FixedArray::kHeaderSize - kHeapObjectTag;
Representation representation = hinstr->value()->representation();
- if (representation.IsInteger32()) {
+ if (representation.IsInteger32() && SmiValuesAre32Bits()) {
ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY);
ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS);
-#ifdef DEBUG
- Register scratch = kScratchRegister;
- __ Load(scratch,
- BuildFastArrayOperand(instr->elements(),
- key,
- FAST_ELEMENTS,
- offset,
- instr->additional_index()),
- Representation::Smi());
- __ AssertSmi(scratch);
-#endif
+ if (FLAG_debug_code) {
+ Register scratch = kScratchRegister;
+ __ Load(scratch,
+ BuildFastArrayOperand(instr->elements(),
+ key,
+ FAST_ELEMENTS,
+ offset,
+ instr->additional_index()),
+ Representation::Smi());
+ __ AssertSmi(scratch);
+ }
// Store int value directly to upper half of the smi.
STATIC_ASSERT(kSmiTag == 0);
- STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
+ ASSERT(kSmiTagSize + kSmiShiftSize == 32);
offset += kPointerSize / 2;
}
@@ -4318,17 +4387,14 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
__ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
ToRegister(instr->temp()), kDontSaveFPRegs);
} else {
+ ASSERT(object_reg.is(rax));
ASSERT(ToRegister(instr->context()).is(rsi));
PushSafepointRegistersScope scope(this);
- if (!object_reg.is(rax)) {
- __ movp(rax, object_reg);
- }
__ Move(rbx, to_map);
bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
- TransitionElementsKindStub stub(from_kind, to_kind, is_js_array);
+ TransitionElementsKindStub stub(isolate(), from_kind, to_kind, is_js_array);
__ CallStub(&stub);
- RecordSafepointWithRegisters(
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
+ RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0);
}
__ bind(&not_applicable);
}
@@ -4348,9 +4414,10 @@ void LCodeGen::DoStringAdd(LStringAdd* instr) {
ASSERT(ToRegister(instr->context()).is(rsi));
ASSERT(ToRegister(instr->left()).is(rdx));
ASSERT(ToRegister(instr->right()).is(rax));
- StringAddStub stub(instr->hydrogen()->flags(),
+ StringAddStub stub(isolate(),
+ instr->hydrogen()->flags(),
instr->hydrogen()->pretenure_flag());
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
@@ -4954,29 +5021,35 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
Register object_;
};
- if (instr->hydrogen()->CanOmitMapChecks()) return;
+ if (instr->hydrogen()->IsStabilityCheck()) {
+ const UniqueSet<Map>* maps = instr->hydrogen()->maps();
+ for (int i = 0; i < maps->size(); ++i) {
+ AddStabilityDependency(maps->at(i).handle());
+ }
+ return;
+ }
LOperand* input = instr->value();
ASSERT(input->IsRegister());
Register reg = ToRegister(input);
DeferredCheckMaps* deferred = NULL;
- if (instr->hydrogen()->has_migration_target()) {
+ if (instr->hydrogen()->HasMigrationTarget()) {
deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
__ bind(deferred->check_maps());
}
- UniqueSet<Map> map_set = instr->hydrogen()->map_set();
+ const UniqueSet<Map>* maps = instr->hydrogen()->maps();
Label success;
- for (int i = 0; i < map_set.size() - 1; i++) {
- Handle<Map> map = map_set.at(i).handle();
+ for (int i = 0; i < maps->size() - 1; i++) {
+ Handle<Map> map = maps->at(i).handle();
__ CompareMap(reg, map);
__ j(equal, &success, Label::kNear);
}
- Handle<Map> map = map_set.at(map_set.size() - 1).handle();
+ Handle<Map> map = maps->at(maps->size() - 1).handle();
__ CompareMap(reg, map);
- if (instr->hydrogen()->has_migration_target()) {
+ if (instr->hydrogen()->HasMigrationTarget()) {
__ j(not_equal, deferred->entry());
} else {
DeoptimizeIf(not_equal, instr->environment());
@@ -5042,7 +5115,7 @@ void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
Register result_reg = ToRegister(instr->result());
if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
__ movq(result_reg, value_reg);
- __ shr(result_reg, Immediate(32));
+ __ shrq(result_reg, Immediate(32));
} else {
__ movd(result_reg, value_reg);
}
@@ -5114,7 +5187,7 @@ void LCodeGen::DoAllocate(LAllocate* instr) {
__ movl(temp, Immediate((size / kPointerSize) - 1));
} else {
temp = ToRegister(instr->size());
- __ sar(temp, Immediate(kPointerSizeLog2));
+ __ sarp(temp, Immediate(kPointerSizeLog2));
__ decl(temp);
}
Label loop;
@@ -5229,10 +5302,11 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
// space for nested functions that don't need literals cloning.
bool pretenure = instr->hydrogen()->pretenure();
if (!pretenure && instr->hydrogen()->has_no_literals()) {
- FastNewClosureStub stub(instr->hydrogen()->strict_mode(),
+ FastNewClosureStub stub(isolate(),
+ instr->hydrogen()->strict_mode(),
instr->hydrogen()->is_generator());
__ Move(rbx, instr->hydrogen()->shared_info());
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
} else {
__ Push(rsi);
__ Push(instr->hydrogen()->shared_info());
@@ -5285,14 +5359,15 @@ Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
Label::Distance false_distance = right_block == next_block ? Label::kNear
: Label::kFar;
Condition final_branch_condition = no_condition;
- if (type_name->Equals(heap()->number_string())) {
+ Factory* factory = isolate()->factory();
+ if (String::Equals(type_name, factory->number_string())) {
__ JumpIfSmi(input, true_label, true_distance);
__ CompareRoot(FieldOperand(input, HeapObject::kMapOffset),
Heap::kHeapNumberMapRootIndex);
final_branch_condition = equal;
- } else if (type_name->Equals(heap()->string_string())) {
+ } else if (String::Equals(type_name, factory->string_string())) {
__ JumpIfSmi(input, false_label, false_distance);
__ CmpObjectType(input, FIRST_NONSTRING_TYPE, input);
__ j(above_equal, false_label, false_distance);
@@ -5300,22 +5375,23 @@ Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
Immediate(1 << Map::kIsUndetectable));
final_branch_condition = zero;
- } else if (type_name->Equals(heap()->symbol_string())) {
+ } else if (String::Equals(type_name, factory->symbol_string())) {
__ JumpIfSmi(input, false_label, false_distance);
__ CmpObjectType(input, SYMBOL_TYPE, input);
final_branch_condition = equal;
- } else if (type_name->Equals(heap()->boolean_string())) {
+ } else if (String::Equals(type_name, factory->boolean_string())) {
__ CompareRoot(input, Heap::kTrueValueRootIndex);
__ j(equal, true_label, true_distance);
__ CompareRoot(input, Heap::kFalseValueRootIndex);
final_branch_condition = equal;
- } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) {
+ } else if (FLAG_harmony_typeof &&
+ String::Equals(type_name, factory->null_string())) {
__ CompareRoot(input, Heap::kNullValueRootIndex);
final_branch_condition = equal;
- } else if (type_name->Equals(heap()->undefined_string())) {
+ } else if (String::Equals(type_name, factory->undefined_string())) {
__ CompareRoot(input, Heap::kUndefinedValueRootIndex);
__ j(equal, true_label, true_distance);
__ JumpIfSmi(input, false_label, false_distance);
@@ -5325,7 +5401,7 @@ Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
Immediate(1 << Map::kIsUndetectable));
final_branch_condition = not_zero;
- } else if (type_name->Equals(heap()->function_string())) {
+ } else if (String::Equals(type_name, factory->function_string())) {
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
__ JumpIfSmi(input, false_label, false_distance);
__ CmpObjectType(input, JS_FUNCTION_TYPE, input);
@@ -5333,7 +5409,7 @@ Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
__ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE);
final_branch_condition = equal;
- } else if (type_name->Equals(heap()->object_string())) {
+ } else if (String::Equals(type_name, factory->object_string())) {
__ JumpIfSmi(input, false_label, false_distance);
if (!FLAG_harmony_typeof) {
__ CompareRoot(input, Heap::kNullValueRootIndex);
@@ -5567,11 +5643,55 @@ void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
}
+void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
+ Register object,
+ Register index) {
+ PushSafepointRegistersScope scope(this);
+ __ Push(object);
+ __ Push(index);
+ __ xorp(rsi, rsi);
+ __ CallRuntimeSaveDoubles(Runtime::kLoadMutableDouble);
+ RecordSafepointWithRegisters(
+ instr->pointer_map(), 2, Safepoint::kNoLazyDeopt);
+ __ StoreToSafepointRegisterSlot(object, rax);
+}
+
+
void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
+ class DeferredLoadMutableDouble V8_FINAL : public LDeferredCode {
+ public:
+ DeferredLoadMutableDouble(LCodeGen* codegen,
+ LLoadFieldByIndex* instr,
+ Register object,
+ Register index)
+ : LDeferredCode(codegen),
+ instr_(instr),
+ object_(object),
+ index_(index) {
+ }
+ virtual void Generate() V8_OVERRIDE {
+ codegen()->DoDeferredLoadMutableDouble(instr_, object_, index_);
+ }
+ virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
+ private:
+ LLoadFieldByIndex* instr_;
+ Register object_;
+ Register index_;
+ };
+
Register object = ToRegister(instr->object());
Register index = ToRegister(instr->index());
+ DeferredLoadMutableDouble* deferred;
+ deferred = new(zone()) DeferredLoadMutableDouble(this, instr, object, index);
+
Label out_of_object, done;
+ __ Move(kScratchRegister, Smi::FromInt(1));
+ __ testp(index, kScratchRegister);
+ __ j(not_zero, deferred->entry());
+
+ __ sarp(index, Immediate(1));
+
__ SmiToInteger32(index, index);
__ cmpl(index, Immediate(0));
__ j(less, &out_of_object, Label::kNear);
@@ -5589,6 +5709,7 @@ void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
index,
times_pointer_size,
FixedArray::kHeaderSize - kPointerSize));
+ __ bind(deferred->exit());
__ bind(&done);
}
diff --git a/deps/v8/src/x64/lithium-codegen-x64.h b/deps/v8/src/x64/lithium-codegen-x64.h
index 37807ede0d..686dc857aa 100644
--- a/deps/v8/src/x64/lithium-codegen-x64.h
+++ b/deps/v8/src/x64/lithium-codegen-x64.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_X64_LITHIUM_CODEGEN_X64_H_
#define V8_X64_LITHIUM_CODEGEN_X64_H_
@@ -35,7 +12,7 @@
#include "lithium-codegen.h"
#include "safepoint-table.h"
#include "scopes.h"
-#include "v8utils.h"
+#include "utils.h"
#include "x64/lithium-gap-resolver-x64.h"
namespace v8 {
@@ -116,6 +93,9 @@ class LCodeGen: public LCodeGenBase {
void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
Label* map_check);
void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
+ void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
+ Register object,
+ Register index);
// Parallel move support.
void DoParallelMove(LParallelMove* move);
@@ -147,8 +127,6 @@ class LCodeGen: public LCodeGenBase {
int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
- void Abort(BailoutReason reason);
-
void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
@@ -224,7 +202,6 @@ class LCodeGen: public LCodeGenBase {
LEnvironment* environment,
Deoptimizer::BailoutType bailout_type);
void DeoptimizeIf(Condition cc, LEnvironment* environment);
- void ApplyCheckIf(Condition cc, LBoundsCheck* check);
bool DeoptEveryNTimes() {
return FLAG_deopt_every_n_times != 0 && !info()->IsStub();
diff --git a/deps/v8/src/x64/lithium-gap-resolver-x64.cc b/deps/v8/src/x64/lithium-gap-resolver-x64.cc
index 7c7fc29e03..7827abd168 100644
--- a/deps/v8/src/x64/lithium-gap-resolver-x64.cc
+++ b/deps/v8/src/x64/lithium-gap-resolver-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
diff --git a/deps/v8/src/x64/lithium-gap-resolver-x64.h b/deps/v8/src/x64/lithium-gap-resolver-x64.h
index f218455b67..5ceacb17d4 100644
--- a/deps/v8/src/x64/lithium-gap-resolver-x64.h
+++ b/deps/v8/src/x64/lithium-gap-resolver-x64.h
@@ -1,29 +1,6 @@
// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_X64_LITHIUM_GAP_RESOLVER_X64_H_
#define V8_X64_LITHIUM_GAP_RESOLVER_X64_H_
diff --git a/deps/v8/src/x64/lithium-x64.cc b/deps/v8/src/x64/lithium-x64.cc
index 8c4f24e8fb..eb9e7dd00a 100644
--- a/deps/v8/src/x64/lithium-x64.cc
+++ b/deps/v8/src/x64/lithium-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -179,12 +156,9 @@ template<int R>
bool LTemplateResultInstruction<R>::MustSignExtendResult(
LPlatformChunk* chunk) const {
HValue* hvalue = this->hydrogen_value();
-
- if (hvalue == NULL) return false;
- if (!hvalue->representation().IsInteger32()) return false;
- if (hvalue->HasRange() && !hvalue->range()->CanBeNegative()) return false;
-
- return chunk->GetDehoistedKeyIds()->Contains(hvalue->id());
+ return hvalue != NULL &&
+ hvalue->representation().IsInteger32() &&
+ chunk->GetDehoistedKeyIds()->Contains(hvalue->id());
}
@@ -465,7 +439,7 @@ LPlatformChunk* LChunkBuilder::Build() {
}
-void LCodeGen::Abort(BailoutReason reason) {
+void LChunkBuilder::Abort(BailoutReason reason) {
info()->set_bailout_reason(reason);
status_ = ABORTED;
}
@@ -652,6 +626,8 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
!hinstr->HasObservableSideEffects();
if (needs_environment && !instr->HasEnvironment()) {
instr = AssignEnvironment(instr);
+ // We can't really figure out if the environment is needed or not.
+ instr->environment()->set_has_been_used();
}
return instr;
@@ -895,7 +871,8 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
// the it was just a plain use), so it is free to move the split child into
// the same register that is used for the use-at-start.
// See https://code.google.com/p/chromium/issues/detail?id=201590
- if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) {
+ if (!(instr->ClobbersRegisters() &&
+ instr->ClobbersDoubleRegisters(isolate()))) {
int fixed = 0;
int used_at_start = 0;
for (UseIterator it(instr); !it.Done(); it.Advance()) {
@@ -1310,7 +1287,7 @@ LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) {
}
-LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
+LInstruction* LChunkBuilder::DoDivI(HDiv* instr) {
ASSERT(instr->representation().IsSmiOrInteger32());
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
@@ -1322,8 +1299,7 @@ LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
instr->CheckFlag(HValue::kCanOverflow) ||
- (!instr->IsMathFloorOfDiv() &&
- !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+ !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
result = AssignEnvironment(result);
}
return result;
@@ -1387,13 +1363,31 @@ LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
}
+LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
+ ASSERT(instr->representation().IsSmiOrInteger32());
+ ASSERT(instr->left()->representation().Equals(instr->representation()));
+ ASSERT(instr->right()->representation().Equals(instr->representation()));
+ LOperand* dividend = UseFixed(instr->left(), rax);
+ LOperand* divisor = UseRegister(instr->right());
+ LOperand* temp = FixedTemp(rdx);
+ LInstruction* result = DefineFixed(new(zone()) LFlooringDivI(
+ dividend, divisor, temp), rax);
+ if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+ instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+ instr->CheckFlag(HValue::kCanOverflow)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
+}
+
+
LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
if (instr->RightIsPowerOf2()) {
return DoFlooringDivByPowerOf2I(instr);
} else if (instr->right()->IsConstant()) {
return DoFlooringDivByConstI(instr);
} else {
- return DoDivI(instr);
+ return DoFlooringDivI(instr);
}
}
@@ -1515,14 +1509,19 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
HValue* right_candidate = instr->BetterRightOperand();
- LOperand* right = use_lea
- ? UseRegisterOrConstantAtStart(right_candidate)
- : UseOrConstantAtStart(right_candidate);
+ LOperand* right;
+ if (instr->representation().IsSmi()) {
+ // We cannot add a tagged immediate to a tagged value,
+ // so we request it in a register.
+ right = UseRegisterAtStart(right_candidate);
+ } else {
+ right = use_lea ? UseRegisterOrConstantAtStart(right_candidate)
+ : UseOrConstantAtStart(right_candidate);
+ }
LAddI* add = new(zone()) LAddI(left, right);
bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
- LInstruction* result = use_lea
- ? DefineAsRegister(add)
- : DefineSameAsFirst(add);
+ LInstruction* result = use_lea ? DefineAsRegister(add)
+ : DefineSameAsFirst(add);
if (can_overflow) {
result = AssignEnvironment(result);
}
@@ -1600,6 +1599,8 @@ LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
LInstruction* LChunkBuilder::DoCompareNumericAndBranch(
HCompareNumericAndBranch* instr) {
+ LInstruction* goto_instr = CheckElideControlInstruction(instr);
+ if (goto_instr != NULL) return goto_instr;
Representation r = instr->representation();
if (r.IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().Equals(r));
@@ -1768,9 +1769,16 @@ LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
- LOperand* value = UseRegisterOrConstantAtStart(instr->index());
- LOperand* length = Use(instr->length());
- return AssignEnvironment(new(zone()) LBoundsCheck(value, length));
+ if (!FLAG_debug_code && instr->skip_check()) return NULL;
+ LOperand* index = UseRegisterOrConstantAtStart(instr->index());
+ LOperand* length = !index->IsConstantOperand()
+ ? UseOrConstantAtStart(instr->length())
+ : UseAtStart(instr->length());
+ LInstruction* result = new(zone()) LBoundsCheck(index, length);
+ if (!FLAG_debug_code || !instr->skip_check()) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
@@ -1804,26 +1812,21 @@ LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
LInstruction* LChunkBuilder::DoChange(HChange* instr) {
Representation from = instr->from();
Representation to = instr->to();
+ HValue* val = instr->value();
if (from.IsSmi()) {
if (to.IsTagged()) {
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
return DefineSameAsFirst(new(zone()) LDummyUse(value));
}
from = Representation::Tagged();
}
- // Only mark conversions that might need to allocate as calling rather than
- // all changes. This makes simple, non-allocating conversion not have to force
- // building a stack frame.
if (from.IsTagged()) {
if (to.IsDouble()) {
- LOperand* value = UseRegister(instr->value());
- LInstruction* res = DefineAsRegister(new(zone()) LNumberUntagD(value));
- if (!instr->value()->representation().IsSmi()) {
- res = AssignEnvironment(res);
- }
- return res;
+ LOperand* value = UseRegister(val);
+ LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value));
+ if (!val->representation().IsSmi()) result = AssignEnvironment(result);
+ return result;
} else if (to.IsSmi()) {
- HValue* val = instr->value();
LOperand* value = UseRegister(val);
if (val->type().IsSmi()) {
return DefineSameAsFirst(new(zone()) LDummyUse(value));
@@ -1831,78 +1834,70 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
} else {
ASSERT(to.IsInteger32());
- HValue* val = instr->value();
- LOperand* value = UseRegister(val);
if (val->type().IsSmi() || val->representation().IsSmi()) {
+ LOperand* value = UseRegister(val);
return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
} else {
+ LOperand* value = UseRegister(val);
bool truncating = instr->CanTruncateToInt32();
LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1);
- LInstruction* res =
+ LInstruction* result =
DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp));
- if (!instr->value()->representation().IsSmi()) {
- // Note: Only deopts in deferred code.
- res = AssignEnvironment(res);
- }
- return res;
+ if (!val->representation().IsSmi()) result = AssignEnvironment(result);
+ return result;
}
}
} else if (from.IsDouble()) {
if (to.IsTagged()) {
info()->MarkAsDeferredCalling();
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
LOperand* temp = TempRegister();
-
- // Make sure that temp and result_temp are different registers.
LUnallocated* result_temp = TempRegister();
LNumberTagD* result = new(zone()) LNumberTagD(value, temp);
return AssignPointerMap(Define(result, result_temp));
} else if (to.IsSmi()) {
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
return AssignEnvironment(
DefineAsRegister(new(zone()) LDoubleToSmi(value)));
} else {
ASSERT(to.IsInteger32());
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value));
- if (!instr->CanTruncateToInt32()) {
- result = AssignEnvironment(result);
- }
+ if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result);
return result;
}
} else if (from.IsInteger32()) {
info()->MarkAsDeferredCalling();
if (to.IsTagged()) {
- HValue* val = instr->value();
- LOperand* value = UseRegister(val);
if (!instr->CheckFlag(HValue::kCanOverflow)) {
+ LOperand* value = UseRegister(val);
return DefineAsRegister(new(zone()) LSmiTag(value));
} else if (val->CheckFlag(HInstruction::kUint32)) {
+ LOperand* value = UseRegister(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = FixedTemp(xmm1);
LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
return AssignPointerMap(DefineSameAsFirst(result));
} else {
+ LOperand* value = UseRegister(val);
LNumberTagI* result = new(zone()) LNumberTagI(value);
return AssignPointerMap(DefineSameAsFirst(result));
}
} else if (to.IsSmi()) {
- HValue* val = instr->value();
LOperand* value = UseRegister(val);
LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
if (instr->CheckFlag(HValue::kCanOverflow)) {
- ASSERT(val->CheckFlag(HValue::kUint32));
result = AssignEnvironment(result);
}
return result;
} else {
- if (instr->value()->CheckFlag(HInstruction::kUint32)) {
+ ASSERT(to.IsDouble());
+ if (val->CheckFlag(HInstruction::kUint32)) {
LOperand* temp = FixedTemp(xmm1);
return DefineAsRegister(
- new(zone()) LUint32ToDouble(UseRegister(instr->value()), temp));
+ new(zone()) LUint32ToDouble(UseRegister(val), temp));
} else {
- ASSERT(to.IsDouble());
- LOperand* value = Use(instr->value());
+ LOperand* value = Use(val);
return DefineAsRegister(new(zone()) LInteger32ToDouble(value));
}
}
@@ -1914,7 +1909,9 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
LOperand* value = UseRegisterAtStart(instr->value());
- return AssignEnvironment(new(zone()) LCheckNonSmi(value));
+ LInstruction* result = new(zone()) LCheckNonSmi(value);
+ if (!instr->value()->IsHeapObject()) result = AssignEnvironment(result);
+ return result;
}
@@ -1938,16 +1935,12 @@ LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
- LOperand* value = NULL;
- if (!instr->CanOmitMapChecks()) {
- value = UseRegisterAtStart(instr->value());
- if (instr->has_migration_target()) info()->MarkAsDeferredCalling();
- }
- LCheckMaps* result = new(zone()) LCheckMaps(value);
- if (!instr->CanOmitMapChecks()) {
- // Note: Only deopts in deferred code.
- AssignEnvironment(result);
- if (instr->has_migration_target()) return AssignPointerMap(result);
+ if (instr->IsStabilityCheck()) return new(zone()) LCheckMaps;
+ LOperand* value = UseRegisterAtStart(instr->value());
+ LInstruction* result = AssignEnvironment(new(zone()) LCheckMaps(value));
+ if (instr->HasMigrationTarget()) {
+ info()->MarkAsDeferredCalling();
+ result = AssignPointerMap(result);
}
return result;
}
@@ -2243,7 +2236,6 @@ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- LOperand* object = UseRegister(instr->object());
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
LOperand* object = UseRegister(instr->object());
LOperand* new_map_reg = TempRegister();
@@ -2252,10 +2244,11 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind(
object, NULL, new_map_reg, temp_reg);
return result;
} else {
+ LOperand* object = UseFixed(instr->object(), rax);
LOperand* context = UseFixed(instr->context(), rsi);
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, context, NULL, NULL);
- return AssignPointerMap(result);
+ return MarkAsCall(result, instr);
}
}
@@ -2411,7 +2404,7 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
} else {
ASSERT(info()->IsStub());
CodeStubInterfaceDescriptor* descriptor =
- info()->code_stub()->GetInterfaceDescriptor(info()->isolate());
+ info()->code_stub()->GetInterfaceDescriptor();
int index = static_cast<int>(instr->index());
Register reg = descriptor->GetParameterRegister(index);
return DefineFixed(result, reg);
@@ -2528,6 +2521,7 @@ LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
HEnvironment* outer = current_block_->last_environment();
+ outer->set_ast_id(instr->ReturnId());
HConstant* undefined = graph()->GetConstantUndefined();
HEnvironment* inner = outer->CopyForInlining(instr->closure(),
instr->arguments_count(),
@@ -2589,7 +2583,9 @@ LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
LOperand* object = UseRegister(instr->object());
LOperand* index = UseTempRegister(instr->index());
- return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index));
+ LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index);
+ LInstruction* result = DefineSameAsFirst(load);
+ return AssignPointerMap(result);
}
diff --git a/deps/v8/src/x64/lithium-x64.h b/deps/v8/src/x64/lithium-x64.h
index 9d9ac1ea17..093b95b4dd 100644
--- a/deps/v8/src/x64/lithium-x64.h
+++ b/deps/v8/src/x64/lithium-x64.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_X64_LITHIUM_X64_H_
#define V8_X64_LITHIUM_X64_H_
@@ -97,6 +74,7 @@ class LCodeGen;
V(Dummy) \
V(FlooringDivByConstI) \
V(FlooringDivByPowerOf2I) \
+ V(FlooringDivI) \
V(ForInCacheArray) \
V(ForInPrepareMap) \
V(FunctionLiteral) \
@@ -256,7 +234,9 @@ class LInstruction : public ZoneObject {
// Interface to the register allocator and iterators.
bool ClobbersTemps() const { return IsCall(); }
bool ClobbersRegisters() const { return IsCall(); }
- virtual bool ClobbersDoubleRegisters() const { return IsCall(); }
+ virtual bool ClobbersDoubleRegisters(Isolate* isolate) const {
+ return IsCall();
+ }
virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { }
@@ -732,14 +712,14 @@ class LDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 2> {
class LDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
public:
- LDivI(LOperand* left, LOperand* right, LOperand* temp) {
- inputs_[0] = left;
- inputs_[1] = right;
+ LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
+ inputs_[0] = dividend;
+ inputs_[1] = divisor;
temps_[0] = temp;
}
- LOperand* left() { return inputs_[0]; }
- LOperand* right() { return inputs_[1]; }
+ LOperand* dividend() { return inputs_[0]; }
+ LOperand* divisor() { return inputs_[1]; }
LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
@@ -794,6 +774,23 @@ class LFlooringDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 3> {
};
+class LFlooringDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
+ public:
+ LFlooringDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
+ inputs_[0] = dividend;
+ inputs_[1] = divisor;
+ temps_[0] = temp;
+ }
+
+ LOperand* dividend() { return inputs_[0]; }
+ LOperand* divisor() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i")
+ DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+};
+
+
class LMulI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public:
LMulI(LOperand* left, LOperand* right) {
@@ -1228,6 +1225,9 @@ class LBitI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
LOperand* right() { return inputs_[1]; }
Token::Value op() const { return hydrogen()->op(); }
+ bool IsInteger32() const {
+ return hydrogen()->representation().IsInteger32();
+ }
DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
DECLARE_HYDROGEN_ACCESSOR(Bitwise)
@@ -1944,7 +1944,7 @@ class LCallRuntime V8_FINAL : public LTemplateInstruction<1, 1, 0> {
DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
- virtual bool ClobbersDoubleRegisters() const V8_OVERRIDE {
+ virtual bool ClobbersDoubleRegisters(Isolate* isolate) const V8_OVERRIDE {
return save_doubles() == kDontSaveFPRegs;
}
@@ -2130,7 +2130,6 @@ class LStoreNamedField V8_FINAL : public LTemplateInstruction<0, 2, 1> {
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
- Handle<Map> transition() const { return hydrogen()->transition_map(); }
Representation representation() const {
return hydrogen()->field_representation();
}
@@ -2339,7 +2338,7 @@ class LCheckInstanceType V8_FINAL : public LTemplateInstruction<0, 1, 0> {
class LCheckMaps V8_FINAL : public LTemplateInstruction<0, 1, 0> {
public:
- explicit LCheckMaps(LOperand* value) {
+ explicit LCheckMaps(LOperand* value = NULL) {
inputs_[0] = value;
}
@@ -2661,6 +2660,8 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
next_block_(NULL),
allocator_(allocator) { }
+ Isolate* isolate() const { return graph_->isolate(); }
+
// Build the sequence for the graph.
LPlatformChunk* Build();
@@ -2681,12 +2682,13 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
LInstruction* DoMathClz32(HUnaryMathOperation* instr);
LInstruction* DoDivByPowerOf2I(HDiv* instr);
LInstruction* DoDivByConstI(HDiv* instr);
- LInstruction* DoDivI(HBinaryOperation* instr);
+ LInstruction* DoDivI(HDiv* instr);
LInstruction* DoModByPowerOf2I(HMod* instr);
LInstruction* DoModByConstI(HMod* instr);
LInstruction* DoModI(HMod* instr);
LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr);
LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr);
+ LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr);
private:
enum Status {
diff --git a/deps/v8/src/x64/macro-assembler-x64.cc b/deps/v8/src/x64/macro-assembler-x64.cc
index 6f313f7a66..17db9bf1a5 100644
--- a/deps/v8/src/x64/macro-assembler-x64.cc
+++ b/deps/v8/src/x64/macro-assembler-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -54,10 +31,10 @@ MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size)
}
-static const int kInvalidRootRegisterDelta = -1;
+static const int64_t kInvalidRootRegisterDelta = -1;
-intptr_t MacroAssembler::RootRegisterDelta(ExternalReference other) {
+int64_t MacroAssembler::RootRegisterDelta(ExternalReference other) {
if (predictable_code_size() &&
(other.address() < reinterpret_cast<Address>(isolate()) ||
other.address() >= reinterpret_cast<Address>(isolate() + 1))) {
@@ -65,17 +42,27 @@ intptr_t MacroAssembler::RootRegisterDelta(ExternalReference other) {
}
Address roots_register_value = kRootRegisterBias +
reinterpret_cast<Address>(isolate()->heap()->roots_array_start());
- intptr_t delta = other.address() - roots_register_value;
+
+ int64_t delta = kInvalidRootRegisterDelta; // Bogus initialization.
+ if (kPointerSize == kInt64Size) {
+ delta = other.address() - roots_register_value;
+ } else {
+ // For x32, zero extend the address to 64-bit and calculate the delta.
+ uint64_t o = static_cast<uint32_t>(
+ reinterpret_cast<intptr_t>(other.address()));
+ uint64_t r = static_cast<uint32_t>(
+ reinterpret_cast<intptr_t>(roots_register_value));
+ delta = o - r;
+ }
return delta;
}
Operand MacroAssembler::ExternalOperand(ExternalReference target,
Register scratch) {
- if (root_array_available_ && !Serializer::enabled()) {
- intptr_t delta = RootRegisterDelta(target);
+ if (root_array_available_ && !Serializer::enabled(isolate())) {
+ int64_t delta = RootRegisterDelta(target);
if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
- Serializer::TooLateToEnableNow();
return Operand(kRootRegister, static_cast<int32_t>(delta));
}
}
@@ -85,10 +72,9 @@ Operand MacroAssembler::ExternalOperand(ExternalReference target,
void MacroAssembler::Load(Register destination, ExternalReference source) {
- if (root_array_available_ && !Serializer::enabled()) {
- intptr_t delta = RootRegisterDelta(source);
+ if (root_array_available_ && !Serializer::enabled(isolate())) {
+ int64_t delta = RootRegisterDelta(source);
if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
- Serializer::TooLateToEnableNow();
movp(destination, Operand(kRootRegister, static_cast<int32_t>(delta)));
return;
}
@@ -104,10 +90,9 @@ void MacroAssembler::Load(Register destination, ExternalReference source) {
void MacroAssembler::Store(ExternalReference destination, Register source) {
- if (root_array_available_ && !Serializer::enabled()) {
- intptr_t delta = RootRegisterDelta(destination);
+ if (root_array_available_ && !Serializer::enabled(isolate())) {
+ int64_t delta = RootRegisterDelta(destination);
if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
- Serializer::TooLateToEnableNow();
movp(Operand(kRootRegister, static_cast<int32_t>(delta)), source);
return;
}
@@ -124,10 +109,9 @@ void MacroAssembler::Store(ExternalReference destination, Register source) {
void MacroAssembler::LoadAddress(Register destination,
ExternalReference source) {
- if (root_array_available_ && !Serializer::enabled()) {
- intptr_t delta = RootRegisterDelta(source);
+ if (root_array_available_ && !Serializer::enabled(isolate())) {
+ int64_t delta = RootRegisterDelta(source);
if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
- Serializer::TooLateToEnableNow();
leap(destination, Operand(kRootRegister, static_cast<int32_t>(delta)));
return;
}
@@ -138,13 +122,12 @@ void MacroAssembler::LoadAddress(Register destination,
int MacroAssembler::LoadAddressSize(ExternalReference source) {
- if (root_array_available_ && !Serializer::enabled()) {
+ if (root_array_available_ && !Serializer::enabled(isolate())) {
// This calculation depends on the internals of LoadAddress.
// It's correctness is ensured by the asserts in the Call
// instruction below.
- intptr_t delta = RootRegisterDelta(source);
+ int64_t delta = RootRegisterDelta(source);
if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
- Serializer::TooLateToEnableNow();
// Operand is leap(scratch, Operand(kRootRegister, delta));
// Opcodes : REX.W 8D ModRM Disp8/Disp32 - 4 or 7.
int size = 4;
@@ -161,7 +144,7 @@ int MacroAssembler::LoadAddressSize(ExternalReference source) {
void MacroAssembler::PushAddress(ExternalReference source) {
int64_t address = reinterpret_cast<int64_t>(source.address());
- if (is_int32(address) && !Serializer::enabled()) {
+ if (is_int32(address) && !Serializer::enabled(isolate())) {
if (emit_debug_code()) {
Move(kScratchRegister, kZapValue, Assembler::RelocInfoNone());
}
@@ -253,7 +236,7 @@ void MacroAssembler::RememberedSetHelper(Register object, // For debug tests.
j(equal, &done, Label::kNear);
}
StoreBufferOverflowStub store_buffer_overflow =
- StoreBufferOverflowStub(save_fp);
+ StoreBufferOverflowStub(isolate(), save_fp);
CallStub(&store_buffer_overflow);
if (and_then == kReturnAtEnd) {
ret(0);
@@ -269,7 +252,7 @@ void MacroAssembler::InNewSpace(Register object,
Condition cc,
Label* branch,
Label::Distance distance) {
- if (Serializer::enabled()) {
+ if (Serializer::enabled(isolate())) {
// Can't do arithmetic on external references if it might get serialized.
// The mask isn't really an address. We load it as an external reference in
// case the size of the new space is different between the snapshot maker
@@ -431,7 +414,8 @@ void MacroAssembler::RecordWrite(Register object,
&done,
Label::kNear);
- RecordWriteStub stub(object, value, address, remembered_set_action, fp_mode);
+ RecordWriteStub stub(isolate(), object, value, address, remembered_set_action,
+ fp_mode);
CallStub(&stub);
bind(&done);
@@ -538,12 +522,12 @@ void MacroAssembler::Abort(BailoutReason reason) {
void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) {
ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs
- Call(stub->GetCode(isolate()), RelocInfo::CODE_TARGET, ast_id);
+ Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id);
}
void MacroAssembler::TailCallStub(CodeStub* stub) {
- Jump(stub->GetCode(isolate()), RelocInfo::CODE_TARGET);
+ Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
}
@@ -558,14 +542,6 @@ bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
}
-void MacroAssembler::IllegalOperation(int num_arguments) {
- if (num_arguments > 0) {
- addp(rsp, Immediate(num_arguments * kPointerSize));
- }
- LoadRoot(rax, Heap::kUndefinedValueRootIndex);
-}
-
-
void MacroAssembler::IndexFromHash(Register hash, Register index) {
// The assert checks that the constants for the maximum number of digits
// for an array index cached in the hash field and the number of bits
@@ -577,7 +553,7 @@ void MacroAssembler::IndexFromHash(Register hash, Register index) {
// key: string key
// hash: key's hash field, including its array index value.
andp(hash, Immediate(String::kArrayIndexValueMask));
- shr(hash, Immediate(String::kHashShift));
+ shrp(hash, Immediate(String::kHashShift));
// Here we actually clobber the key which will be used if calling into
// runtime later. However as the new key is the numeric value of a string key
// there is no difference in using either key.
@@ -591,10 +567,7 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f,
// If the expected number of arguments of the runtime function is
// constant, we check that the actual number of arguments match the
// expectation.
- if (f->nargs >= 0 && f->nargs != num_arguments) {
- IllegalOperation(num_arguments);
- return;
- }
+ CHECK(f->nargs < 0 || f->nargs == num_arguments);
// TODO(1236192): Most runtime routines don't need the number of
// arguments passed in because it is constant. At some point we
@@ -602,7 +575,7 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f,
// smarter.
Set(rax, num_arguments);
LoadAddress(rbx, ExternalReference(f, isolate()));
- CEntryStub ces(f->result_size, save_doubles);
+ CEntryStub ces(isolate(), f->result_size, save_doubles);
CallStub(&ces);
}
@@ -612,7 +585,7 @@ void MacroAssembler::CallExternalReference(const ExternalReference& ext,
Set(rax, num_arguments);
LoadAddress(rbx, ext);
- CEntryStub stub(1);
+ CEntryStub stub(isolate(), 1);
CallStub(&stub);
}
@@ -660,7 +633,7 @@ void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) {
void MacroAssembler::CallApiFunctionAndReturn(
Register function_address,
- Address thunk_address,
+ ExternalReference thunk_ref,
Register thunk_last_arg,
int stack_space,
Operand return_value_operand,
@@ -707,16 +680,13 @@ void MacroAssembler::CallApiFunctionAndReturn(
Label profiler_disabled;
Label end_profiler_check;
- bool* is_profiling_flag =
- isolate()->cpu_profiler()->is_profiling_address();
- STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
- Move(rax, is_profiling_flag, RelocInfo::EXTERNAL_REFERENCE);
+ Move(rax, ExternalReference::is_profiling_address(isolate()));
cmpb(Operand(rax, 0), Immediate(0));
j(zero, &profiler_disabled);
// Third parameter is the address of the actual getter function.
Move(thunk_last_arg, function_address);
- Move(rax, thunk_address, RelocInfo::EXTERNAL_REFERENCE);
+ Move(rax, thunk_ref);
jmp(&end_profiler_check);
bind(&profiler_disabled);
@@ -821,8 +791,8 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& ext,
int result_size) {
// Set the entry point and jump to the C entry runtime stub.
LoadAddress(rbx, ext);
- CEntryStub ces(result_size);
- jmp(ces.GetCode(isolate()), RelocInfo::CODE_TARGET);
+ CEntryStub ces(isolate(), result_size);
+ jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
}
@@ -981,7 +951,6 @@ void MacroAssembler::Set(const Operand& dst, intptr_t x) {
movp(dst, kScratchRegister);
}
} else {
- ASSERT(kPointerSize == kInt32Size);
movp(dst, Immediate(static_cast<int32_t>(x)));
}
}
@@ -998,11 +967,18 @@ bool MacroAssembler::IsUnsafeInt(const int32_t x) {
void MacroAssembler::SafeMove(Register dst, Smi* src) {
ASSERT(!dst.is(kScratchRegister));
- ASSERT(SmiValuesAre32Bits()); // JIT cookie can be converted to Smi.
if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
- Move(dst, Smi::FromInt(src->value() ^ jit_cookie()));
- Move(kScratchRegister, Smi::FromInt(jit_cookie()));
- xorq(dst, kScratchRegister);
+ if (SmiValuesAre32Bits()) {
+ // JIT cookie can be converted to Smi.
+ Move(dst, Smi::FromInt(src->value() ^ jit_cookie()));
+ Move(kScratchRegister, Smi::FromInt(jit_cookie()));
+ xorp(dst, kScratchRegister);
+ } else {
+ ASSERT(SmiValuesAre31Bits());
+ int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src));
+ movp(dst, Immediate(value ^ jit_cookie()));
+ xorp(dst, Immediate(jit_cookie()));
+ }
} else {
Move(dst, src);
}
@@ -1010,11 +986,18 @@ void MacroAssembler::SafeMove(Register dst, Smi* src) {
void MacroAssembler::SafePush(Smi* src) {
- ASSERT(SmiValuesAre32Bits()); // JIT cookie can be converted to Smi.
if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
- Push(Smi::FromInt(src->value() ^ jit_cookie()));
- Move(kScratchRegister, Smi::FromInt(jit_cookie()));
- xorq(Operand(rsp, 0), kScratchRegister);
+ if (SmiValuesAre32Bits()) {
+ // JIT cookie can be converted to Smi.
+ Push(Smi::FromInt(src->value() ^ jit_cookie()));
+ Move(kScratchRegister, Smi::FromInt(jit_cookie()));
+ xorp(Operand(rsp, 0), kScratchRegister);
+ } else {
+ ASSERT(SmiValuesAre31Bits());
+ int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src));
+ Push(Immediate(value ^ jit_cookie()));
+ xorp(Operand(rsp, 0), Immediate(jit_cookie()));
+ }
} else {
Push(src);
}
@@ -1096,7 +1079,7 @@ void MacroAssembler::Integer32ToSmi(Register dst, Register src) {
if (!dst.is(src)) {
movl(dst, src);
}
- shl(dst, Immediate(kSmiShift));
+ shlp(dst, Immediate(kSmiShift));
}
@@ -1108,8 +1091,15 @@ void MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) {
Abort(kInteger32ToSmiFieldWritingToNonSmiLocation);
bind(&ok);
}
- ASSERT(kSmiShift % kBitsPerByte == 0);
- movl(Operand(dst, kSmiShift / kBitsPerByte), src);
+
+ if (SmiValuesAre32Bits()) {
+ ASSERT(kSmiShift % kBitsPerByte == 0);
+ movl(Operand(dst, kSmiShift / kBitsPerByte), src);
+ } else {
+ ASSERT(SmiValuesAre31Bits());
+ Integer32ToSmi(kScratchRegister, src);
+ movp(dst, kScratchRegister);
+ }
}
@@ -1121,7 +1111,7 @@ void MacroAssembler::Integer64PlusConstantToSmi(Register dst,
} else {
leal(dst, Operand(src, constant));
}
- shl(dst, Immediate(kSmiShift));
+ shlp(dst, Immediate(kSmiShift));
}
@@ -1130,12 +1120,24 @@ void MacroAssembler::SmiToInteger32(Register dst, Register src) {
if (!dst.is(src)) {
movp(dst, src);
}
- shr(dst, Immediate(kSmiShift));
+
+ if (SmiValuesAre32Bits()) {
+ shrp(dst, Immediate(kSmiShift));
+ } else {
+ ASSERT(SmiValuesAre31Bits());
+ sarl(dst, Immediate(kSmiShift));
+ }
}
void MacroAssembler::SmiToInteger32(Register dst, const Operand& src) {
- movl(dst, Operand(src, kSmiShift / kBitsPerByte));
+ if (SmiValuesAre32Bits()) {
+ movl(dst, Operand(src, kSmiShift / kBitsPerByte));
+ } else {
+ ASSERT(SmiValuesAre31Bits());
+ movl(dst, src);
+ sarl(dst, Immediate(kSmiShift));
+ }
}
@@ -1144,12 +1146,22 @@ void MacroAssembler::SmiToInteger64(Register dst, Register src) {
if (!dst.is(src)) {
movp(dst, src);
}
- sar(dst, Immediate(kSmiShift));
+ sarp(dst, Immediate(kSmiShift));
+ if (kPointerSize == kInt32Size) {
+ // Sign extend to 64-bit.
+ movsxlq(dst, dst);
+ }
}
void MacroAssembler::SmiToInteger64(Register dst, const Operand& src) {
- movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte));
+ if (SmiValuesAre32Bits()) {
+ movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte));
+ } else {
+ ASSERT(SmiValuesAre31Bits());
+ movp(dst, src);
+ SmiToInteger64(dst, dst);
+ }
}
@@ -1199,7 +1211,12 @@ void MacroAssembler::SmiCompare(const Operand& dst, Register src) {
void MacroAssembler::SmiCompare(const Operand& dst, Smi* src) {
AssertSmi(dst);
- cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value()));
+ if (SmiValuesAre32Bits()) {
+ cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value()));
+ } else {
+ ASSERT(SmiValuesAre31Bits());
+ cmpl(dst, Immediate(src));
+ }
}
@@ -1212,7 +1229,13 @@ void MacroAssembler::Cmp(const Operand& dst, Smi* src) {
void MacroAssembler::SmiCompareInteger32(const Operand& dst, Register src) {
- cmpl(Operand(dst, kSmiShift / kBitsPerByte), src);
+ if (SmiValuesAre32Bits()) {
+ cmpl(Operand(dst, kSmiShift / kBitsPerByte), src);
+ } else {
+ ASSERT(SmiValuesAre31Bits());
+ SmiToInteger32(kScratchRegister, dst);
+ cmpl(kScratchRegister, src);
+ }
}
@@ -1229,9 +1252,9 @@ void MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst,
movp(dst, src);
}
if (power < kSmiShift) {
- sar(dst, Immediate(kSmiShift - power));
+ sarp(dst, Immediate(kSmiShift - power));
} else if (power > kSmiShift) {
- shl(dst, Immediate(power - kSmiShift));
+ shlp(dst, Immediate(power - kSmiShift));
}
}
@@ -1241,7 +1264,7 @@ void MacroAssembler::PositiveSmiDivPowerOfTwoToInteger32(Register dst,
int power) {
ASSERT((0 <= power) && (power < 32));
if (dst.is(src)) {
- shr(dst, Immediate(power + kSmiShift));
+ shrp(dst, Immediate(power + kSmiShift));
} else {
UNIMPLEMENTED(); // Not used.
}
@@ -1284,7 +1307,7 @@ Condition MacroAssembler::CheckNonNegativeSmi(Register src) {
STATIC_ASSERT(kSmiTag == 0);
// Test that both bits of the mask 0x8000000000000001 are zero.
movp(kScratchRegister, src);
- rol(kScratchRegister, Immediate(1));
+ rolp(kScratchRegister, Immediate(1));
testb(kScratchRegister, Immediate(3));
return zero;
}
@@ -1295,8 +1318,15 @@ Condition MacroAssembler::CheckBothSmi(Register first, Register second) {
return CheckSmi(first);
}
STATIC_ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3);
- leal(kScratchRegister, Operand(first, second, times_1, 0));
- testb(kScratchRegister, Immediate(0x03));
+ if (SmiValuesAre32Bits()) {
+ leal(kScratchRegister, Operand(first, second, times_1, 0));
+ testb(kScratchRegister, Immediate(0x03));
+ } else {
+ ASSERT(SmiValuesAre31Bits());
+ movl(kScratchRegister, first);
+ orl(kScratchRegister, second);
+ testb(kScratchRegister, Immediate(kSmiTagMask));
+ }
return zero;
}
@@ -1308,7 +1338,7 @@ Condition MacroAssembler::CheckBothNonNegativeSmi(Register first,
}
movp(kScratchRegister, first);
orp(kScratchRegister, second);
- rol(kScratchRegister, Immediate(1));
+ rolp(kScratchRegister, Immediate(1));
testl(kScratchRegister, Immediate(3));
return zero;
}
@@ -1342,16 +1372,28 @@ Condition MacroAssembler::CheckIsMinSmi(Register src) {
Condition MacroAssembler::CheckInteger32ValidSmiValue(Register src) {
- // A 32-bit integer value can always be converted to a smi.
- return always;
+ if (SmiValuesAre32Bits()) {
+ // A 32-bit integer value can always be converted to a smi.
+ return always;
+ } else {
+ ASSERT(SmiValuesAre31Bits());
+ cmpl(src, Immediate(0xc0000000));
+ return positive;
+ }
}
Condition MacroAssembler::CheckUInteger32ValidSmiValue(Register src) {
- // An unsigned 32-bit integer value is valid as long as the high bit
- // is not set.
- testl(src, src);
- return positive;
+ if (SmiValuesAre32Bits()) {
+ // An unsigned 32-bit integer value is valid as long as the high bit
+ // is not set.
+ testl(src, src);
+ return positive;
+ } else {
+ ASSERT(SmiValuesAre31Bits());
+ testl(src, Immediate(0xc0000000));
+ return zero;
+ }
}
@@ -1494,7 +1536,13 @@ void MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) {
void MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) {
if (constant->value() != 0) {
- addl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(constant->value()));
+ if (SmiValuesAre32Bits()) {
+ addl(Operand(dst, kSmiShift / kBitsPerByte),
+ Immediate(constant->value()));
+ } else {
+ ASSERT(SmiValuesAre31Bits());
+ addp(dst, Immediate(constant));
+ }
}
}
@@ -1952,8 +2000,14 @@ void MacroAssembler::SmiMod(Register dst,
void MacroAssembler::SmiNot(Register dst, Register src) {
ASSERT(!dst.is(kScratchRegister));
ASSERT(!src.is(kScratchRegister));
- // Set tag and padding bits before negating, so that they are zero afterwards.
- movl(kScratchRegister, Immediate(~0));
+ if (SmiValuesAre32Bits()) {
+ // Set tag and padding bits before negating, so that they are zero
+ // afterwards.
+ movl(kScratchRegister, Immediate(~0));
+ } else {
+ ASSERT(SmiValuesAre31Bits());
+ movl(kScratchRegister, Immediate(1));
+ }
if (dst.is(src)) {
xorp(dst, kScratchRegister);
} else {
@@ -2034,8 +2088,8 @@ void MacroAssembler::SmiShiftArithmeticRightConstant(Register dst,
ASSERT(is_uint5(shift_value));
if (shift_value > 0) {
if (dst.is(src)) {
- sar(dst, Immediate(shift_value + kSmiShift));
- shl(dst, Immediate(kSmiShift));
+ sarp(dst, Immediate(shift_value + kSmiShift));
+ shlp(dst, Immediate(kSmiShift));
} else {
UNIMPLEMENTED(); // Not used.
}
@@ -2050,7 +2104,7 @@ void MacroAssembler::SmiShiftLeftConstant(Register dst,
movp(dst, src);
}
if (shift_value > 0) {
- shl(dst, Immediate(shift_value));
+ shlp(dst, Immediate(shift_value));
}
}
@@ -2067,8 +2121,8 @@ void MacroAssembler::SmiShiftLogicalRightConstant(
testp(dst, dst);
j(negative, on_not_smi_result, near_jump);
}
- shr(dst, Immediate(shift_value + kSmiShift));
- shl(dst, Immediate(kSmiShift));
+ shrq(dst, Immediate(shift_value + kSmiShift));
+ shlq(dst, Immediate(kSmiShift));
}
}
@@ -2084,7 +2138,7 @@ void MacroAssembler::SmiShiftLeft(Register dst,
SmiToInteger32(rcx, src2);
// Shift amount specified by lower 5 bits, not six as the shl opcode.
andq(rcx, Immediate(0x1f));
- shl_cl(dst);
+ shlq_cl(dst);
}
@@ -2107,8 +2161,8 @@ void MacroAssembler::SmiShiftLogicalRight(Register dst,
}
SmiToInteger32(rcx, src2);
orl(rcx, Immediate(kSmiShift));
- shr_cl(dst); // Shift is rcx modulo 0x1f + 32.
- shl(dst, Immediate(kSmiShift));
+ shrq_cl(dst); // Shift is rcx modulo 0x1f + 32.
+ shlq(dst, Immediate(kSmiShift));
testq(dst, dst);
if (src1.is(rcx) || src2.is(rcx)) {
Label positive_result;
@@ -2144,8 +2198,8 @@ void MacroAssembler::SmiShiftArithmeticRight(Register dst,
}
SmiToInteger32(rcx, src2);
orl(rcx, Immediate(kSmiShift));
- sar_cl(dst); // Shift 32 + original rcx & 0x1f.
- shl(dst, Immediate(kSmiShift));
+ sarp_cl(dst); // Shift 32 + original rcx & 0x1f.
+ shlp(dst, Immediate(kSmiShift));
if (src1.is(rcx)) {
movp(src1, kScratchRegister);
} else if (src2.is(rcx)) {
@@ -2194,41 +2248,78 @@ void MacroAssembler::SelectNonSmi(Register dst,
SmiIndex MacroAssembler::SmiToIndex(Register dst,
Register src,
int shift) {
- ASSERT(is_uint6(shift));
- // There is a possible optimization if shift is in the range 60-63, but that
- // will (and must) never happen.
- if (!dst.is(src)) {
- movq(dst, src);
- }
- if (shift < kSmiShift) {
- sar(dst, Immediate(kSmiShift - shift));
+ if (SmiValuesAre32Bits()) {
+ ASSERT(is_uint6(shift));
+ // There is a possible optimization if shift is in the range 60-63, but that
+ // will (and must) never happen.
+ if (!dst.is(src)) {
+ movp(dst, src);
+ }
+ if (shift < kSmiShift) {
+ sarp(dst, Immediate(kSmiShift - shift));
+ } else {
+ shlp(dst, Immediate(shift - kSmiShift));
+ }
+ return SmiIndex(dst, times_1);
} else {
- shl(dst, Immediate(shift - kSmiShift));
+ ASSERT(SmiValuesAre31Bits());
+ ASSERT(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1));
+ if (!dst.is(src)) {
+ movp(dst, src);
+ }
+ // We have to sign extend the index register to 64-bit as the SMI might
+ // be negative.
+ movsxlq(dst, dst);
+ if (shift == times_1) {
+ sarq(dst, Immediate(kSmiShift));
+ return SmiIndex(dst, times_1);
+ }
+ return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1));
}
- return SmiIndex(dst, times_1);
}
+
SmiIndex MacroAssembler::SmiToNegativeIndex(Register dst,
Register src,
int shift) {
- // Register src holds a positive smi.
- ASSERT(is_uint6(shift));
- if (!dst.is(src)) {
- movq(dst, src);
- }
- negq(dst);
- if (shift < kSmiShift) {
- sar(dst, Immediate(kSmiShift - shift));
+ if (SmiValuesAre32Bits()) {
+ // Register src holds a positive smi.
+ ASSERT(is_uint6(shift));
+ if (!dst.is(src)) {
+ movp(dst, src);
+ }
+ negp(dst);
+ if (shift < kSmiShift) {
+ sarp(dst, Immediate(kSmiShift - shift));
+ } else {
+ shlp(dst, Immediate(shift - kSmiShift));
+ }
+ return SmiIndex(dst, times_1);
} else {
- shl(dst, Immediate(shift - kSmiShift));
+ ASSERT(SmiValuesAre31Bits());
+ ASSERT(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1));
+ if (!dst.is(src)) {
+ movp(dst, src);
+ }
+ negq(dst);
+ if (shift == times_1) {
+ sarq(dst, Immediate(kSmiShift));
+ return SmiIndex(dst, times_1);
+ }
+ return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1));
}
- return SmiIndex(dst, times_1);
}
void MacroAssembler::AddSmiField(Register dst, const Operand& src) {
- ASSERT_EQ(0, kSmiShift % kBitsPerByte);
- addl(dst, Operand(src, kSmiShift / kBitsPerByte));
+ if (SmiValuesAre32Bits()) {
+ ASSERT_EQ(0, kSmiShift % kBitsPerByte);
+ addl(dst, Operand(src, kSmiShift / kBitsPerByte));
+ } else {
+ ASSERT(SmiValuesAre31Bits());
+ SmiToInteger32(kScratchRegister, src);
+ addl(dst, kScratchRegister);
+ }
}
@@ -2243,32 +2334,39 @@ void MacroAssembler::Push(Smi* source) {
}
-void MacroAssembler::PushInt64AsTwoSmis(Register src, Register scratch) {
+void MacroAssembler::PushRegisterAsTwoSmis(Register src, Register scratch) {
+ ASSERT(!src.is(scratch));
movp(scratch, src);
// High bits.
- shr(src, Immediate(64 - kSmiShift));
- shl(src, Immediate(kSmiShift));
+ shrp(src, Immediate(kPointerSize * kBitsPerByte - kSmiShift));
+ shlp(src, Immediate(kSmiShift));
Push(src);
// Low bits.
- shl(scratch, Immediate(kSmiShift));
+ shlp(scratch, Immediate(kSmiShift));
Push(scratch);
}
-void MacroAssembler::PopInt64AsTwoSmis(Register dst, Register scratch) {
+void MacroAssembler::PopRegisterAsTwoSmis(Register dst, Register scratch) {
+ ASSERT(!dst.is(scratch));
Pop(scratch);
// Low bits.
- shr(scratch, Immediate(kSmiShift));
+ shrp(scratch, Immediate(kSmiShift));
Pop(dst);
- shr(dst, Immediate(kSmiShift));
+ shrp(dst, Immediate(kSmiShift));
// High bits.
- shl(dst, Immediate(64 - kSmiShift));
+ shlp(dst, Immediate(kPointerSize * kBitsPerByte - kSmiShift));
orp(dst, scratch);
}
void MacroAssembler::Test(const Operand& src, Smi* source) {
- testl(Operand(src, kIntSize), Immediate(source->value()));
+ if (SmiValuesAre32Bits()) {
+ testl(Operand(src, kIntSize), Immediate(source->value()));
+ } else {
+ ASSERT(SmiValuesAre31Bits());
+ testl(src, Immediate(source));
+ }
}
@@ -2315,7 +2413,7 @@ void MacroAssembler::LookupNumberStringCache(Register object,
// but times_twice_pointer_size (multiplication by 16) scale factor
// is not supported by addrmode on x64 platform.
// So we have to premultiply entry index before lookup.
- shl(scratch, Immediate(kPointerSizeLog2 + 1));
+ shlp(scratch, Immediate(kPointerSizeLog2 + 1));
Register index = scratch;
Register probe = mask;
@@ -2338,7 +2436,7 @@ void MacroAssembler::LookupNumberStringCache(Register object,
// but times_twice_pointer_size (multiplication by 16) scale factor
// is not supported by addrmode on x64 platform.
// So we have to premultiply entry index before lookup.
- shl(scratch, Immediate(kPointerSizeLog2 + 1));
+ shlp(scratch, Immediate(kPointerSizeLog2 + 1));
// Check if the entry is the smi we are looking for.
cmpp(object,
@@ -2576,11 +2674,24 @@ void MacroAssembler::Drop(int stack_elements) {
}
+void MacroAssembler::DropUnderReturnAddress(int stack_elements,
+ Register scratch) {
+ ASSERT(stack_elements > 0);
+ if (kPointerSize == kInt64Size && stack_elements == 1) {
+ popq(MemOperand(rsp, 0));
+ return;
+ }
+
+ PopReturnAddressTo(scratch);
+ Drop(stack_elements);
+ PushReturnAddressFrom(scratch);
+}
+
+
void MacroAssembler::Push(Register src) {
if (kPointerSize == kInt64Size) {
pushq(src);
} else {
- ASSERT(kPointerSize == kInt32Size);
// x32 uses 64-bit push for rbp in the prologue.
ASSERT(src.code() != rbp.code());
leal(rsp, Operand(rsp, -4));
@@ -2593,7 +2704,6 @@ void MacroAssembler::Push(const Operand& src) {
if (kPointerSize == kInt64Size) {
pushq(src);
} else {
- ASSERT(kPointerSize == kInt32Size);
movp(kScratchRegister, src);
leal(rsp, Operand(rsp, -4));
movp(Operand(rsp, 0), kScratchRegister);
@@ -2601,11 +2711,20 @@ void MacroAssembler::Push(const Operand& src) {
}
+void MacroAssembler::PushQuad(const Operand& src) {
+ if (kPointerSize == kInt64Size) {
+ pushq(src);
+ } else {
+ movp(kScratchRegister, src);
+ pushq(kScratchRegister);
+ }
+}
+
+
void MacroAssembler::Push(Immediate value) {
if (kPointerSize == kInt64Size) {
pushq(value);
} else {
- ASSERT(kPointerSize == kInt32Size);
leal(rsp, Operand(rsp, -4));
movp(Operand(rsp, 0), value);
}
@@ -2616,7 +2735,6 @@ void MacroAssembler::PushImm32(int32_t imm32) {
if (kPointerSize == kInt64Size) {
pushq_imm32(imm32);
} else {
- ASSERT(kPointerSize == kInt32Size);
leal(rsp, Operand(rsp, -4));
movp(Operand(rsp, 0), Immediate(imm32));
}
@@ -2627,7 +2745,6 @@ void MacroAssembler::Pop(Register dst) {
if (kPointerSize == kInt64Size) {
popq(dst);
} else {
- ASSERT(kPointerSize == kInt32Size);
// x32 uses 64-bit pop for rbp in the epilogue.
ASSERT(dst.code() != rbp.code());
movp(dst, Operand(rsp, 0));
@@ -2640,7 +2757,6 @@ void MacroAssembler::Pop(const Operand& dst) {
if (kPointerSize == kInt64Size) {
popq(dst);
} else {
- ASSERT(kPointerSize == kInt32Size);
Register scratch = dst.AddressUsesRegister(kScratchRegister)
? kSmiConstantRegister : kScratchRegister;
movp(scratch, Operand(rsp, 0));
@@ -2656,10 +2772,44 @@ void MacroAssembler::Pop(const Operand& dst) {
}
-void MacroAssembler::TestBit(const Operand& src, int bits) {
+void MacroAssembler::PopQuad(const Operand& dst) {
+ if (kPointerSize == kInt64Size) {
+ popq(dst);
+ } else {
+ popq(kScratchRegister);
+ movp(dst, kScratchRegister);
+ }
+}
+
+
+void MacroAssembler::LoadSharedFunctionInfoSpecialField(Register dst,
+ Register base,
+ int offset) {
+ ASSERT(offset > SharedFunctionInfo::kLengthOffset &&
+ offset <= SharedFunctionInfo::kSize &&
+ (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1));
+ if (kPointerSize == kInt64Size) {
+ movsxlq(dst, FieldOperand(base, offset));
+ } else {
+ movp(dst, FieldOperand(base, offset));
+ SmiToInteger32(dst, dst);
+ }
+}
+
+
+void MacroAssembler::TestBitSharedFunctionInfoSpecialField(Register base,
+ int offset,
+ int bits) {
+ ASSERT(offset > SharedFunctionInfo::kLengthOffset &&
+ offset <= SharedFunctionInfo::kSize &&
+ (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1));
+ if (kPointerSize == kInt32Size) {
+ // On x32, this field is represented by SMI.
+ bits += kSmiShift;
+ }
int byte_offset = bits / kBitsPerByte;
int bit_in_byte = bits & (kBitsPerByte - 1);
- testb(Operand(src, byte_offset), Immediate(1 << bit_in_byte));
+ testb(FieldOperand(base, offset + byte_offset), Immediate(1 << bit_in_byte));
}
@@ -2673,7 +2823,6 @@ void MacroAssembler::Jump(const Operand& op) {
if (kPointerSize == kInt64Size) {
jmp(op);
} else {
- ASSERT(kPointerSize == kInt32Size);
movp(kScratchRegister, op);
jmp(kScratchRegister);
}
@@ -2715,7 +2864,6 @@ void MacroAssembler::Call(const Operand& op) {
if (kPointerSize == kInt64Size) {
call(op);
} else {
- ASSERT(kPointerSize == kInt32Size);
movp(kScratchRegister, op);
call(kScratchRegister);
}
@@ -2893,7 +3041,7 @@ void MacroAssembler::JumpToHandlerEntry() {
// a fixed array of (smi-tagged) code offsets.
// rax = exception, rdi = code object, rdx = state.
movp(rbx, FieldOperand(rdi, Code::kHandlerTableOffset));
- shr(rdx, Immediate(StackHandler::kKindWidth));
+ shrp(rdx, Immediate(StackHandler::kKindWidth));
movp(rdx,
FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize));
SmiToInteger64(rdx, rdx);
@@ -3188,8 +3336,8 @@ void MacroAssembler::LoadUint32(XMMRegister dst,
void MacroAssembler::SlowTruncateToI(Register result_reg,
Register input_reg,
int offset) {
- DoubleToIStub stub(input_reg, result_reg, offset, true);
- call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
+ DoubleToIStub stub(isolate(), input_reg, result_reg, offset, true);
+ call(stub.GetCode(), RelocInfo::CODE_TARGET);
}
@@ -3212,6 +3360,8 @@ void MacroAssembler::TruncateHeapNumberToI(Register result_reg,
}
bind(&done);
+ // Keep our invariant that the upper 32 bits are zero.
+ movl(result_reg, result_reg);
}
@@ -3228,6 +3378,8 @@ void MacroAssembler::TruncateDoubleToI(Register result_reg,
addp(rsp, Immediate(kDoubleSize));
bind(&done);
+ // Keep our invariant that the upper 32 bits are zero.
+ movl(result_reg, result_reg);
}
@@ -3498,9 +3650,9 @@ void MacroAssembler::TryGetFunctionPrototype(Register function,
FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
// It's not smi-tagged (stored in the top half of a smi-tagged 8-byte
// field).
- TestBit(FieldOperand(kScratchRegister,
- SharedFunctionInfo::kCompilerHintsOffset),
- SharedFunctionInfo::kBoundFunction);
+ TestBitSharedFunctionInfoSpecialField(kScratchRegister,
+ SharedFunctionInfo::kCompilerHintsOffset,
+ SharedFunctionInfo::kBoundFunction);
j(not_zero, miss);
}
@@ -3573,15 +3725,13 @@ void MacroAssembler::DecrementCounter(StatsCounter* counter, int value) {
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
void MacroAssembler::DebugBreak() {
Set(rax, 0); // No arguments.
LoadAddress(rbx, ExternalReference(Runtime::kDebugBreak, isolate()));
- CEntryStub ces(1);
+ CEntryStub ces(isolate(), 1);
ASSERT(AllowThisStubCall(&ces));
- Call(ces.GetCode(isolate()), RelocInfo::DEBUG_BREAK);
+ Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
}
-#endif // ENABLE_DEBUGGER_SUPPORT
void MacroAssembler::InvokeCode(Register code,
@@ -3627,8 +3777,8 @@ void MacroAssembler::InvokeFunction(Register function,
ASSERT(function.is(rdi));
movp(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
movp(rsi, FieldOperand(function, JSFunction::kContextOffset));
- movsxlq(rbx,
- FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset));
+ LoadSharedFunctionInfoSpecialField(rbx, rdx,
+ SharedFunctionInfo::kFormalParameterCountOffset);
// Advances rdx to the end of the Code object header, to the start of
// the executable code.
movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
@@ -4882,7 +5032,7 @@ void MacroAssembler::GetMarkBits(Register addr_reg,
shrl(rcx, Immediate(kPointerSizeLog2));
andp(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1));
movl(mask_reg, Immediate(1));
- shl_cl(mask_reg);
+ shlp_cl(mask_reg);
}
@@ -4966,7 +5116,7 @@ void MacroAssembler::EnsureNotWhite(
addp(length, Immediate(0x04));
// Value now either 4 (if ASCII) or 8 (if UC16), i.e. char-size shifted by 2.
imulp(length, FieldOperand(value, String::kLengthOffset));
- shr(length, Immediate(2 + kSmiTagSize + kSmiShiftSize));
+ shrp(length, Immediate(2 + kSmiTagSize + kSmiShiftSize));
addp(length, Immediate(SeqString::kHeaderSize + kObjectAlignmentMask));
andp(length, Immediate(~kObjectAlignmentMask));
@@ -5065,7 +5215,7 @@ void MacroAssembler::JumpIfDictionaryInPrototypeChain(
movp(current, FieldOperand(current, HeapObject::kMapOffset));
movp(scratch1, FieldOperand(current, Map::kBitField2Offset));
andp(scratch1, Immediate(Map::kElementsKindMask));
- shr(scratch1, Immediate(Map::kElementsKindShift));
+ shrp(scratch1, Immediate(Map::kElementsKindShift));
cmpp(scratch1, Immediate(DICTIONARY_ELEMENTS));
j(equal, found);
movp(current, FieldOperand(current, Map::kPrototypeOffset));
diff --git a/deps/v8/src/x64/macro-assembler-x64.h b/deps/v8/src/x64/macro-assembler-x64.h
index af65a65465..d9893d6210 100644
--- a/deps/v8/src/x64/macro-assembler-x64.h
+++ b/deps/v8/src/x64/macro-assembler-x64.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_X64_MACRO_ASSEMBLER_X64_H_
#define V8_X64_MACRO_ASSEMBLER_X64_H_
@@ -291,12 +268,10 @@ class MacroAssembler: public Assembler {
RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
SmiCheck smi_check = INLINE_SMI_CHECK);
-#ifdef ENABLE_DEBUGGER_SUPPORT
// ---------------------------------------------------------------------------
// Debugger Support
void DebugBreak();
-#endif
// Generates function and stub prologue code.
void Prologue(PrologueFrameMode frame_mode);
@@ -657,10 +632,10 @@ class MacroAssembler: public Assembler {
Register src,
int shift_value);
void SmiShiftLogicalRightConstant(Register dst,
- Register src,
- int shift_value,
- Label* on_not_smi_result,
- Label::Distance near_jump = Label::kFar);
+ Register src,
+ int shift_value,
+ Label* on_not_smi_result,
+ Label::Distance near_jump = Label::kFar);
void SmiShiftArithmeticRightConstant(Register dst,
Register src,
int shift_value);
@@ -726,12 +701,12 @@ class MacroAssembler: public Assembler {
void Push(Smi* smi);
- // Save away a 64-bit integer on the stack as two 32-bit integers
+ // Save away a raw integer with pointer size on the stack as two integers
// masquerading as smis so that the garbage collector skips visiting them.
- void PushInt64AsTwoSmis(Register src, Register scratch = kScratchRegister);
- // Reconstruct a 64-bit integer from two 32-bit integers masquerading as
- // smis on the top of stack.
- void PopInt64AsTwoSmis(Register dst, Register scratch = kScratchRegister);
+ void PushRegisterAsTwoSmis(Register src, Register scratch = kScratchRegister);
+ // Reconstruct a raw integer with pointer size from two integers masquerading
+ // as smis on the top of stack.
+ void PopRegisterAsTwoSmis(Register dst, Register scratch = kScratchRegister);
void Test(const Operand& dst, Smi* source);
@@ -813,8 +788,13 @@ class MacroAssembler: public Assembler {
// Move if the registers are not identical.
void Move(Register target, Register source);
- // Bit-field support.
- void TestBit(const Operand& dst, int bit_index);
+ // TestBit and Load SharedFunctionInfo special field.
+ void TestBitSharedFunctionInfoSpecialField(Register base,
+ int offset,
+ int bit_index);
+ void LoadSharedFunctionInfoSpecialField(Register dst,
+ Register base,
+ int offset);
// Handle support
void Move(Register dst, Handle<Object> source);
@@ -835,14 +815,21 @@ class MacroAssembler: public Assembler {
// Emit code to discard a non-negative number of pointer-sized elements
// from the stack, clobbering only the rsp register.
void Drop(int stack_elements);
+ // Emit code to discard a positive number of pointer-sized elements
+ // from the stack under the return address which remains on the top,
+ // clobbering the rsp register.
+ void DropUnderReturnAddress(int stack_elements,
+ Register scratch = kScratchRegister);
void Call(Label* target) { call(target); }
void Push(Register src);
void Push(const Operand& src);
+ void PushQuad(const Operand& src);
void Push(Immediate value);
void PushImm32(int32_t imm32);
void Pop(Register dst);
void Pop(const Operand& dst);
+ void PopQuad(const Operand& dst);
void PushReturnAddressFrom(Register src) { pushq(src); }
void PopReturnAddressTo(Register dst) { popq(dst); }
void Move(Register dst, ExternalReference ext) {
@@ -1026,9 +1013,9 @@ class MacroAssembler: public Assembler {
void DecodeField(Register reg) {
static const int shift = Field::kShift + kSmiShift;
static const int mask = Field::kMask >> Field::kShift;
- shr(reg, Immediate(shift));
+ shrp(reg, Immediate(shift));
andp(reg, Immediate(mask));
- shl(reg, Immediate(kSmiShift));
+ shlp(reg, Immediate(kSmiShift));
}
// Abort execution if argument is not a number, enabled via --debug-code.
@@ -1218,10 +1205,6 @@ class MacroAssembler: public Assembler {
Label* miss,
bool miss_on_bound_function = false);
- // Generates code for reporting that an illegal operation has
- // occurred.
- void IllegalOperation(int num_arguments);
-
// Picks out an array index from the hash field.
// Register use:
// hash - holds the index's hash. Clobbered.
@@ -1310,7 +1293,7 @@ class MacroAssembler: public Assembler {
// caller-save registers. Restores context. On return removes
// stack_space * kPointerSize (GCed).
void CallApiFunctionAndReturn(Register function_address,
- Address thunk_address,
+ ExternalReference thunk_ref,
Register thunk_last_arg,
int stack_space,
Operand return_value_operand,
@@ -1460,7 +1443,7 @@ class MacroAssembler: public Assembler {
// modified. It may be the "smi 1 constant" register.
Register GetSmiConstant(Smi* value);
- intptr_t RootRegisterDelta(ExternalReference other);
+ int64_t RootRegisterDelta(ExternalReference other);
// Moves the smi value to the destination register.
void LoadSmiConstant(Register dst, Smi* value);
@@ -1501,13 +1484,6 @@ class MacroAssembler: public Assembler {
Register scratch,
AllocationFlags flags);
- // Helper for PopHandleScope. Allowed to perform a GC and returns
- // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and
- // possibly returns a failure object indicating an allocation failure.
- Object* PopHandleScopeHelper(Register saved,
- Register scratch,
- bool gc_allowed);
-
// Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
void InNewSpace(Register object,
Register scratch,
diff --git a/deps/v8/src/x64/regexp-macro-assembler-x64.cc b/deps/v8/src/x64/regexp-macro-assembler-x64.cc
index c819c71cb9..6a9a264f97 100644
--- a/deps/v8/src/x64/regexp-macro-assembler-x64.cc
+++ b/deps/v8/src/x64/regexp-macro-assembler-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -241,8 +218,8 @@ void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase(
int start_reg,
Label* on_no_match) {
Label fallthrough;
- __ movq(rdx, register_location(start_reg)); // Offset of start of capture
- __ movq(rbx, register_location(start_reg + 1)); // Offset of end of capture
+ ReadPositionFromRegister(rdx, start_reg); // Offset of start of capture
+ ReadPositionFromRegister(rbx, start_reg + 1); // Offset of end of capture
__ subp(rbx, rdx); // Length of capture.
// -----------------------
@@ -390,8 +367,8 @@ void RegExpMacroAssemblerX64::CheckNotBackReference(
Label fallthrough;
// Find length of back-referenced capture.
- __ movq(rdx, register_location(start_reg));
- __ movq(rax, register_location(start_reg + 1));
+ ReadPositionFromRegister(rdx, start_reg); // Offset of start of capture
+ ReadPositionFromRegister(rax, start_reg + 1); // Offset of end of capture
__ subp(rax, rdx); // Length to check.
// Fail on partial or illegal capture (start of capture after end of capture).
@@ -692,12 +669,12 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
#else
// GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9 (and then on stack).
// Push register parameters on stack for reference.
- ASSERT_EQ(kInputString, -1 * kPointerSize);
- ASSERT_EQ(kStartIndex, -2 * kPointerSize);
- ASSERT_EQ(kInputStart, -3 * kPointerSize);
- ASSERT_EQ(kInputEnd, -4 * kPointerSize);
- ASSERT_EQ(kRegisterOutput, -5 * kPointerSize);
- ASSERT_EQ(kNumOutputRegisters, -6 * kPointerSize);
+ ASSERT_EQ(kInputString, -1 * kRegisterSize);
+ ASSERT_EQ(kStartIndex, -2 * kRegisterSize);
+ ASSERT_EQ(kInputStart, -3 * kRegisterSize);
+ ASSERT_EQ(kInputEnd, -4 * kRegisterSize);
+ ASSERT_EQ(kRegisterOutput, -5 * kRegisterSize);
+ ASSERT_EQ(kNumOutputRegisters, -6 * kRegisterSize);
__ pushq(rdi);
__ pushq(rsi);
__ pushq(rdx);
@@ -747,7 +724,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
// Load input position.
__ movp(rdi, Operand(rbp, kInputStart));
// Set up rdi to be negative offset from string end.
- __ subp(rdi, rsi);
+ __ subq(rdi, rsi);
// Set rax to address of char before start of the string
// (effectively string position -1).
__ movp(rbx, Operand(rbp, kStartIndex));
@@ -831,14 +808,14 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
__ addp(rcx, rdx);
}
for (int i = 0; i < num_saved_registers_; i++) {
- __ movq(rax, register_location(i));
+ __ movp(rax, register_location(i));
if (i == 0 && global_with_zero_length_check()) {
// Keep capture start in rdx for the zero-length check later.
__ movp(rdx, rax);
}
__ addp(rax, rcx); // Convert to index from start, not end.
if (mode_ == UC16) {
- __ sar(rax, Immediate(1)); // Convert byte index to character index.
+ __ sarp(rax, Immediate(1)); // Convert byte index to character index.
}
__ movl(Operand(rbx, i * kIntSize), rax);
}
@@ -1084,13 +1061,31 @@ void RegExpMacroAssemblerX64::PushRegister(int register_index,
}
+STATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size);
+
+
void RegExpMacroAssemblerX64::ReadCurrentPositionFromRegister(int reg) {
- __ movq(rdi, register_location(reg));
+ if (kPointerSize == kInt64Size) {
+ __ movq(rdi, register_location(reg));
+ } else {
+ // Need sign extension for x32 as rdi might be used as an index register.
+ __ movsxlq(rdi, register_location(reg));
+ }
+}
+
+
+void RegExpMacroAssemblerX64::ReadPositionFromRegister(Register dst, int reg) {
+ if (kPointerSize == kInt64Size) {
+ __ movq(dst, register_location(reg));
+ } else {
+ // Need sign extension for x32 as dst might be used as an index register.
+ __ movsxlq(dst, register_location(reg));
+ }
}
void RegExpMacroAssemblerX64::ReadStackPointerFromRegister(int reg) {
- __ movq(backtrack_stackpointer(), register_location(reg));
+ __ movp(backtrack_stackpointer(), register_location(reg));
__ addp(backtrack_stackpointer(), Operand(rbp, kStackHighEnd));
}
@@ -1215,7 +1210,7 @@ int RegExpMacroAssemblerX64::CheckStackGuardState(Address* return_address,
ASSERT(*return_address <=
re_code->instruction_start() + re_code->instruction_size());
- MaybeObject* result = Execution::HandleStackGuardInterrupt(isolate);
+ Object* result = Execution::HandleStackGuardInterrupt(isolate);
if (*code_handle != re_code) { // Return address no longer valid
intptr_t delta = code_handle->address() - re_code->address();
diff --git a/deps/v8/src/x64/regexp-macro-assembler-x64.h b/deps/v8/src/x64/regexp-macro-assembler-x64.h
index b230ea47fc..e9f6a35ddb 100644
--- a/deps/v8/src/x64/regexp-macro-assembler-x64.h
+++ b/deps/v8/src/x64/regexp-macro-assembler-x64.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_X64_REGEXP_MACRO_ASSEMBLER_X64_H_
#define V8_X64_REGEXP_MACRO_ASSEMBLER_X64_H_
@@ -135,8 +112,8 @@ class RegExpMacroAssemblerX64: public NativeRegExpMacroAssembler {
// Offsets from rbp of function parameters and stored registers.
static const int kFramePointer = 0;
// Above the frame pointer - function parameters and return address.
- static const int kReturn_eip = kFramePointer + kPointerSize;
- static const int kFrameAlign = kReturn_eip + kPointerSize;
+ static const int kReturn_eip = kFramePointer + kRegisterSize;
+ static const int kFrameAlign = kReturn_eip + kRegisterSize;
#ifdef _WIN64
// Parameters (first four passed as registers, but with room on stack).
@@ -145,49 +122,50 @@ class RegExpMacroAssemblerX64: public NativeRegExpMacroAssembler {
// use this space to store the register passed parameters.
static const int kInputString = kFrameAlign;
// StartIndex is passed as 32 bit int.
- static const int kStartIndex = kInputString + kPointerSize;
- static const int kInputStart = kStartIndex + kPointerSize;
- static const int kInputEnd = kInputStart + kPointerSize;
- static const int kRegisterOutput = kInputEnd + kPointerSize;
+ static const int kStartIndex = kInputString + kRegisterSize;
+ static const int kInputStart = kStartIndex + kRegisterSize;
+ static const int kInputEnd = kInputStart + kRegisterSize;
+ static const int kRegisterOutput = kInputEnd + kRegisterSize;
// For the case of global regular expression, we have room to store at least
// one set of capture results. For the case of non-global regexp, we ignore
// this value. NumOutputRegisters is passed as 32-bit value. The upper
// 32 bit of this 64-bit stack slot may contain garbage.
- static const int kNumOutputRegisters = kRegisterOutput + kPointerSize;
- static const int kStackHighEnd = kNumOutputRegisters + kPointerSize;
+ static const int kNumOutputRegisters = kRegisterOutput + kRegisterSize;
+ static const int kStackHighEnd = kNumOutputRegisters + kRegisterSize;
// DirectCall is passed as 32 bit int (values 0 or 1).
- static const int kDirectCall = kStackHighEnd + kPointerSize;
- static const int kIsolate = kDirectCall + kPointerSize;
+ static const int kDirectCall = kStackHighEnd + kRegisterSize;
+ static const int kIsolate = kDirectCall + kRegisterSize;
#else
// In AMD64 ABI Calling Convention, the first six integer parameters
// are passed as registers, and caller must allocate space on the stack
// if it wants them stored. We push the parameters after the frame pointer.
- static const int kInputString = kFramePointer - kPointerSize;
- static const int kStartIndex = kInputString - kPointerSize;
- static const int kInputStart = kStartIndex - kPointerSize;
- static const int kInputEnd = kInputStart - kPointerSize;
- static const int kRegisterOutput = kInputEnd - kPointerSize;
+ static const int kInputString = kFramePointer - kRegisterSize;
+ static const int kStartIndex = kInputString - kRegisterSize;
+ static const int kInputStart = kStartIndex - kRegisterSize;
+ static const int kInputEnd = kInputStart - kRegisterSize;
+ static const int kRegisterOutput = kInputEnd - kRegisterSize;
+
// For the case of global regular expression, we have room to store at least
// one set of capture results. For the case of non-global regexp, we ignore
// this value.
- static const int kNumOutputRegisters = kRegisterOutput - kPointerSize;
+ static const int kNumOutputRegisters = kRegisterOutput - kRegisterSize;
static const int kStackHighEnd = kFrameAlign;
- static const int kDirectCall = kStackHighEnd + kPointerSize;
- static const int kIsolate = kDirectCall + kPointerSize;
+ static const int kDirectCall = kStackHighEnd + kRegisterSize;
+ static const int kIsolate = kDirectCall + kRegisterSize;
#endif
#ifdef _WIN64
// Microsoft calling convention has three callee-saved registers
// (that we are using). We push these after the frame pointer.
- static const int kBackup_rsi = kFramePointer - kPointerSize;
- static const int kBackup_rdi = kBackup_rsi - kPointerSize;
- static const int kBackup_rbx = kBackup_rdi - kPointerSize;
+ static const int kBackup_rsi = kFramePointer - kRegisterSize;
+ static const int kBackup_rdi = kBackup_rsi - kRegisterSize;
+ static const int kBackup_rbx = kBackup_rdi - kRegisterSize;
static const int kLastCalleeSaveRegister = kBackup_rbx;
#else
// AMD64 Calling Convention has only one callee-save register that
// we use. We push this after the frame pointer (and after the
// parameters).
- static const int kBackup_rbx = kNumOutputRegisters - kPointerSize;
+ static const int kBackup_rbx = kNumOutputRegisters - kRegisterSize;
static const int kLastCalleeSaveRegister = kBackup_rbx;
#endif
@@ -268,6 +246,8 @@ class RegExpMacroAssemblerX64: public NativeRegExpMacroAssembler {
// Increments the stack pointer (rcx) by a word size.
inline void Drop();
+ inline void ReadPositionFromRegister(Register dst, int reg);
+
Isolate* isolate() const { return masm_.isolate(); }
MacroAssembler masm_;
diff --git a/deps/v8/src/x64/simulator-x64.cc b/deps/v8/src/x64/simulator-x64.cc
index 448b025a6b..f7f2fb4bb4 100644
--- a/deps/v8/src/x64/simulator-x64.cc
+++ b/deps/v8/src/x64/simulator-x64.cc
@@ -1,26 +1,3 @@
// Copyright 2009 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
diff --git a/deps/v8/src/x64/simulator-x64.h b/deps/v8/src/x64/simulator-x64.h
index 8aba70181f..a43728f01d 100644
--- a/deps/v8/src/x64/simulator-x64.h
+++ b/deps/v8/src/x64/simulator-x64.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_X64_SIMULATOR_X64_H_
#define V8_X64_SIMULATOR_X64_H_
diff --git a/deps/v8/src/x64/stub-cache-x64.cc b/deps/v8/src/x64/stub-cache-x64.cc
index 13e822da2b..537f412351 100644
--- a/deps/v8/src/x64/stub-cache-x64.cc
+++ b/deps/v8/src/x64/stub-cache-x64.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -420,7 +397,7 @@ void StubCompiler::GenerateFastApiCall(MacroAssembler* masm,
api_function_address, function_address, RelocInfo::EXTERNAL_REFERENCE);
// Jump to stub.
- CallApiFunctionStub stub(is_store, call_data_undefined, argc);
+ CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
__ TailCallStub(&stub);
}
@@ -495,6 +472,21 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
__ JumpIfSmi(value_reg, miss_label);
+ HeapType* field_type = descriptors->GetFieldType(descriptor);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ Label do_store;
+ while (true) {
+ __ CompareMap(value_reg, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ j(not_equal, miss_label);
+ break;
+ }
+ __ j(equal, &do_store, Label::kNear);
+ }
+ __ bind(&do_store);
+ }
} else if (representation.IsDouble()) {
Label do_store, heap_number;
__ AllocateHeapNumber(storage_reg, scratch1, slow);
@@ -639,6 +631,21 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
__ JumpIfSmi(value_reg, miss_label);
+ HeapType* field_type = lookup->GetFieldType();
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ Label do_store;
+ while (true) {
+ __ CompareMap(value_reg, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ j(not_equal, miss_label);
+ break;
+ }
+ __ j(equal, &do_store, Label::kNear);
+ }
+ __ bind(&do_store);
+ }
} else if (representation.IsDouble()) {
// Load the double storage.
if (index < 0) {
@@ -741,7 +748,9 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
int depth = 0;
Handle<JSObject> current = Handle<JSObject>::null();
- if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant());
+ if (type->IsConstant()) {
+ current = Handle<JSObject>::cast(type->AsConstant()->Value());
+ }
Handle<JSObject> prototype = Handle<JSObject>::null();
Handle<Map> current_map = receiver_map;
Handle<Map> holder_map(holder->map());
@@ -764,7 +773,7 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
name = factory()->InternalizeString(Handle<String>::cast(name));
}
ASSERT(current.is_null() ||
- current->property_dictionary()->FindEntry(*name) ==
+ current->property_dictionary()->FindEntry(name) ==
NameDictionary::kNotFound);
GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
@@ -908,15 +917,17 @@ void LoadStubCompiler::GenerateLoadField(Register reg,
Representation representation) {
if (!reg.is(receiver())) __ movp(receiver(), reg);
if (kind() == Code::LOAD_IC) {
- LoadFieldStub stub(field.is_inobject(holder),
+ LoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
field.translate(holder),
representation);
- GenerateTailCall(masm(), stub.GetCode(isolate()));
+ GenerateTailCall(masm(), stub.GetCode());
} else {
- KeyedLoadFieldStub stub(field.is_inobject(holder),
+ KeyedLoadFieldStub stub(isolate(),
+ field.is_inobject(holder),
field.translate(holder),
representation);
- GenerateTailCall(masm(), stub.GetCode(isolate()));
+ GenerateTailCall(masm(), stub.GetCode());
}
}
@@ -961,7 +972,7 @@ void LoadStubCompiler::GenerateLoadCallback(
Address getter_address = v8::ToCData<Address>(callback->getter());
__ Move(api_function_address, getter_address, RelocInfo::EXTERNAL_REFERENCE);
- CallApiGetterStub stub;
+ CallApiGetterStub stub(isolate());
__ TailCallStub(&stub);
}
@@ -1064,17 +1075,6 @@ void LoadStubCompiler::GenerateLoadInterceptor(
}
-void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
- Label success;
- // Check that the object is a boolean.
- __ Cmp(object, factory()->true_value());
- __ j(equal, &success);
- __ Cmp(object, factory()->false_value());
- __ j(not_equal, miss);
- __ bind(&success);
-}
-
-
Handle<Code> StoreStubCompiler::CompileStoreCallback(
Handle<JSObject> object,
Handle<JSObject> holder,
diff --git a/deps/v8/src/zone-allocator.h b/deps/v8/src/zone-allocator.h
index 7ed1713904..8501c35b27 100644
--- a/deps/v8/src/zone-allocator.h
+++ b/deps/v8/src/zone-allocator.h
@@ -1,33 +1,12 @@
// Copyright 2014 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ZONE_ALLOCATOR_H_
#define V8_ZONE_ALLOCATOR_H_
+#include <limits>
+
#include "zone.h"
namespace v8 {
@@ -57,16 +36,14 @@ class zone_allocator {
pointer address(reference x) const {return &x;}
const_pointer address(const_reference x) const {return &x;}
- pointer allocate(size_type count, const void* hint = 0) {
- size_t size = count * sizeof(value_type);
- size = RoundUp(size, kPointerSize);
- return static_cast<pointer>(zone_->New(size));
+ pointer allocate(size_type n, const void* hint = 0) {
+ return static_cast<pointer>(zone_->NewArray<value_type>(
+ static_cast<int>(n)));
}
void deallocate(pointer p, size_type) { /* noop for Zones */ }
size_type max_size() const throw() {
- size_type max = static_cast<size_type>(-1) / sizeof(T);
- return (max > 0 ? max : 1);
+ return std::numeric_limits<int>::max() / sizeof(value_type);
}
void construct(pointer p, const T& val) {
new(static_cast<void*>(p)) T(val);
diff --git a/deps/v8/src/zone-containers.h b/deps/v8/src/zone-containers.h
index 31672b62db..c4a1055f9c 100644
--- a/deps/v8/src/zone-containers.h
+++ b/deps/v8/src/zone-containers.h
@@ -1,29 +1,6 @@
// Copyright 2014 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ZONE_CONTAINERS_H_
#define V8_ZONE_CONTAINERS_H_
diff --git a/deps/v8/src/zone-inl.h b/deps/v8/src/zone-inl.h
index 9b82c05408..c17f33c4aa 100644
--- a/deps/v8/src/zone-inl.h
+++ b/deps/v8/src/zone-inl.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ZONE_INL_H_
#define V8_ZONE_INL_H_
@@ -39,7 +16,6 @@
#include "counters.h"
#include "isolate.h"
#include "utils.h"
-#include "v8-counters.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/src/zone.cc b/deps/v8/src/zone.cc
index 4f91371294..49efc5a746 100644
--- a/deps/v8/src/zone.cc
+++ b/deps/v8/src/zone.cc
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include <string.h>
diff --git a/deps/v8/src/zone.h b/deps/v8/src/zone.h
index 83421b3963..573e13e1d4 100644
--- a/deps/v8/src/zone.h
+++ b/deps/v8/src/zone.h
@@ -1,29 +1,6 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_ZONE_H_
#define V8_ZONE_H_